Commit f5ee7b1c authored by 王纵's avatar 王纵

页面大保存默认逻辑

parent bddd72f8
<!--
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-31 15:09:30
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-05 17:46:19
* @Version: 1.0.0
* @Description: 按钮渲染
* @Copyright: Copyright (c) 2021, Hand-RongJing
-->
<template>
<div class="d-buttons">
<van-button
v-for="btn in defaultBtns"
round
type="info"
size="mini"
:key="btn.name"
class="d-button"
@click="handlClick(btn)"
>{{btn.description}}</van-button>
<fragment v-if="buttons.length > num">
<span class="d-button-more" @click="more"><van-icon name="more-o" />更多</span>
<div class="d-button-more-content" :style="{display: moreVisible ? 'flex' : 'none'}">
<van-button
v-for="btn in hideBtns"
round
type="info"
size="mini"
:key="btn.name"
class="d-button"
@click="handlClick(btn)"
>{{btn.description}}</van-button>
</div>
</fragment>
<fragment v-else>
</fragment>
</div>
</template>
<script>
import { Button, Icon } from 'vant';
export default {
name: 'DButtons',
components: {
[Button.name]: Button,
[Icon.name]: Icon,
},
props: {
tabInfo: { // 配置信息
type: Object,
default: () => {}
},
buttons: {
type: Array,
default: () => [],
},
},
data () {
return {
num: 2,
defaultBtns: [],
hideBtns: [],
moreVisible: false,
}
},
mounted() {
document.addEventListener('click', this.clickEle, false)
this.init();
},
destroyed () {
document.removeEventListener('click', this.clickEle, false)
},
methods: {
clickEle (e) {
let content = document.querySelector('.d-buttons')
if ((content && !content.contains(e.target))) {
this.moreVisible = false;
}
},
init() {
if(this.buttons.length > this.num) {
this.defaultBtns = this.buttons.slice(0, this.num);
this.hideBtns = this.buttons.slice(this.num, this.buttons.length);
} else {
this.defaultBtns = [...this.buttons];
}
},
more() {
this.moreVisible = true;
},
handlClick(btn) {
this.moreVisible = false;
console.log(btn.name)
}
},
}
</script>
<style scoped lang="less">
.d-buttons {
display: flex;
position: relative;
align-items: center;
justify-content: end;
.d-button {
padding: 0 12px;
height: 24px;
margin-left: 12px;
}
.d-button-more {
color: #666666;
font-size: 12px;
padding: 5px 8px;
margin-left: 12px;
}
.d-button-more-content {
z-index: 1;
position: absolute;
right: 0;
top: 100%;
display: flex;
flex-direction: column;
.d-button {
margin-top: 8px;
}
}
}
</style>
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-01 09:55:12
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-12 11:15:28
* @LastEditTime: 2024-08-13 15:47:01
* @Version: 1.0.0
* @Description: 动态渲染-复选框组件
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -18,6 +18,7 @@
<van-field
:disabled="disabled"
:required="required"
:name="name"
:rules="[{ required, message: `请填写${label}` }]"
>
<d-label :label="label" :help="help" slot="label" />
......@@ -42,6 +43,10 @@ export default {
DLabel
},
props: {
name: {
type: String,
default: ''
},
help: {
type: String,
default: ''
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-01 09:55:12
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-09 18:21:29
* @LastEditTime: 2024-08-14 09:29:36
* @Version: 1.0.0
* @Description: 动态渲染-日期组件
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -22,6 +22,7 @@
readonly
v-model="currentValue"
placeholder="请选择"
:name="name"
:disabled="disabled"
:required="required"
@click="showDate(true)"
......@@ -30,7 +31,7 @@
>
<d-label :label="label" :help="help" slot="label" />
<template slot="right-icon" >
<van-icon name="clear" v-show="clearable && currentValue" @click="clear"/>
<van-icon name="clear" v-show="!disabled && clearable && currentValue" @click="clear"/>
<img src="../../../assets/date-icon.png" alt="" class="right-icon"/>
</template>
</van-field>
......@@ -70,6 +71,10 @@ export default {
type: String,
default: 'DatePicker'
},
name: {
type: String,
default: ''
},
help: {
type: String,
default: ''
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-01 09:55:12
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-12 14:09:57
* @LastEditTime: 2024-08-13 15:46:33
* @Version: 1.0.0
* @Description: 动态渲染-文本框组件
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -13,6 +13,7 @@
v-model="currentValue"
placeholder="请输入"
@input="fieldInput"
:name="name"
:type="fieldType[type]"
:disabled="disabled"
:required="required"
......@@ -49,6 +50,10 @@ export default {
type: String,
default: 'TextField',
},
name: {
type: String,
default: ''
},
help: {
type: String,
default: ''
......@@ -58,7 +63,7 @@ export default {
default: ''
},
value: {
type: String,
type: String | Number,
default: '',
},
disabled: {
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-01 09:55:12
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-09 22:36:54
* @LastEditTime: 2024-08-14 09:28:23
* @Version: 1.0.0
* @Description: 动态渲染-Lov
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -26,6 +26,7 @@
<van-field
v-model="fieldValue"
:name="name"
:disabled="disabled"
:required="required"
:rules="[{ required, message: `请选择${label}` }]"
......@@ -38,7 +39,7 @@
</div>
</template>
<template slot="right-icon" >
<van-icon name="clear" v-show="clearable && !(!currentValue || currentValue.length === 0)" @click="clear"/>
<van-icon name="clear" v-show="!disabled && clearable && !(!currentValue || currentValue.length === 0)" @click="clear"/>
<van-icon name="arrow" />
</template>
</van-field>
......@@ -115,6 +116,10 @@ export default {
type: Object,
default: () => {}
},
name: {
type: String,
default: ''
},
help: {
type: String,
default: ''
......@@ -163,6 +168,17 @@ export default {
options: [],
}
},
watch: {
value: {
handler(newValue, oldValue) {
if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
this.currentValue = newValue;
this.fieldValue = newValue ? JSON.stringify(newValue) : '';
}
},
deep: true
}
},
mounted() {
this.getLovConfig();
},
......@@ -170,7 +186,6 @@ export default {
getLovConfig() {
hlsHttp.get(`/hpfm/v1/${getOrganizationId()}/lov-view/info`, {viewCode: this.fieldConfig.lovCode}).then(res => {
this.lovConfig = res;
// this.getLovData();
});
},
getLovData() {
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-01 09:55:12
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-09 22:36:43
* @LastEditTime: 2024-08-14 09:28:54
* @Version: 1.0.0
* @Description: 动态渲染-Select
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -24,6 +24,7 @@
<van-field
v-model="fieldValue"
:name="name"
:disabled="disabled"
:required="required"
:rules="[{ required, message: `请选择${label}` }]"
......@@ -36,33 +37,32 @@
</div>
</template>
<template slot="right-icon" >
<van-icon name="clear" v-show="clearable && (currentValue.length || currentValue.meaning)" @click="clear"/>
<van-icon name="clear" v-show="!disabled && clearable && (currentValue.length || currentValue.meaning)" @click="clear"/>
<van-icon name="arrow" />
</template>
</van-field>
<van-popup v-model="visible" round position="bottom" class="d-select-popup">
<div class="d-select-popup">
<div class="title">
<span class="cancel" @click="showSelectOption(false)">取消</span>
<span class="title-label">请选择{{fieldConfig.description}}</span>
<span class="confirm" @click="onConfirm">确定</span>
</div>
<ul class="list">
<li
v-for="(option, index) in options"
:class="option.selected ? 'item active' : 'item'"
:key="option.value"
@click="selectOption(option, index)"
>{{option.meaning}}</li>
</ul>
<div class="title">
<span class="cancel" @click="showSelectOption(false)">取消</span>
<span class="title-label">请选择{{fieldConfig.description}}</span>
<span class="confirm" @click="onConfirm">确定</span>
</div>
<ul class="list">
<li
v-for="(option, index) in options"
:class="option._selected ? 'item active' : 'item'"
:key="option.value"
@click="selectOption(option, index)"
>{{option.meaning}}</li>
</ul>
</van-popup>
</div>
</template>
<script>
import {isNumber} from 'lodash';
import {Cell, Switch, Icon, Popup, Field} from 'vant';
import DLabel from './DLabel';
import hlsHttp from '../../../utils/hlsHttp';
......@@ -87,6 +87,10 @@ export default {
type: Boolean,
default: false
},
name: {
type: String,
default: ''
},
help: {
type: String,
default: ''
......@@ -96,7 +100,7 @@ export default {
default: ''
},
value: {
type: String,
type: String | Number,
default: '',
},
disabled: {
......@@ -111,6 +115,10 @@ export default {
type: Boolean,
default: false,
},
cascadesParams: {
type: Object,
default: () => ({})
}
},
data () {
return {
......@@ -123,28 +131,54 @@ export default {
options: [],
}
},
watch: {
value: function(newValue, oldValue) {
if (newValue !== oldValue) {
if (this.multiple) {
if (JSON.stringify(newValue) !== JSON.stringify(this.currentValue)) {
this.formatValue();
}
} else if (newValue !== this.currentValue.value) {
this.formatValue();
}
}
},
cascadesParams: {
handler(newValue, oldValue) {
if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
this.getOptions();
}
},
deep: true
}
},
mounted() {
this.getOptions();
},
methods: {
getOptions() {
hlsHttp.get(`/hpfm/v1/${getOrganizationId()}/lovs/data`, {lovCode: this.fieldConfig.lookupCode}).then(res => {
// 处理值
const selectData = [];
const valueArr = (this.value || '').split(',');
this.options = res.map(item => {
if (valueArr.includes(item.value)) {
item.selected = true;
selectData.push({...item});
}
return item;
});
if (this.multiple) { // 多选
this.currentValue = selectData;
hlsHttp.get(`/hpfm/v1/${getOrganizationId()}/lovs/data`, {lovCode: this.fieldConfig.lookupCode, ...this.cascadesParams}).then(res => {
this.options = res.map(item => ({...item, _selected: false}));
});
},
formatValue() {
const selectData = [];
const valueArr = isNumber(this.value) ? [this.value] : (this.value || '').split(',');
this.options = this.options.map(item => {
if (valueArr.includes(item.value)) {
item._selected = true;
selectData.push({...item});
} else {
this.currentValue = selectData.length ? selectData : { meaning: '', value: '' };
item._selected = false;
}
return item;
});
if (this.multiple) { // 多选
this.currentValue = selectData;
} else {
this.currentValue = selectData.length ? selectData[0] : { meaning: '', value: '' };
}
this.fieldValue = this.currentValue ? JSON.stringify(this.currentValue) : ''
},
showSelectOption(flag) {
if (!this.disabled) {
......@@ -152,7 +186,7 @@ export default {
}
},
clear() {
this.options = this.options.map(o => ({...o, selected: false}));
this.options = this.options.map(o => ({...o, _selected: false}));
if (this.multiple) {
this.currentValue = [];
} else {
......@@ -162,20 +196,20 @@ export default {
},
onConfirm() {
if (this.multiple) {
this.currentValue = this.options.filter(o => o.selected);
this.currentValue = this.options.filter(o => o._selected);
const values = this.currentValue.map(o => o.value).join(',');
this.inputValue(values);
} else {
this.currentValue = this.options.find(o => o.selected);
this.currentValue = this.options.find(o => o._selected);
this.inputValue(this.currentValue.value);
}
this.showSelectOption(false);
},
selectOption(val, index) {
if (!this.multiple) {
this.options = this.options.map(o => ({...o, selected: false}))
this.options = this.options.map(o => ({...o, _selected: false}))
}
this.$set(this.options[index], 'selected', !this.options[index].selected);
this.$set(this.options[index], '_selected', !this.options[index]._selected);
},
inputValue(val) {
this.fieldValue = val ? JSON.stringify(val) : '';
......@@ -196,6 +230,7 @@ export default {
<style lang="less">
@import './index.less';
.d-select-popup {
max-height: 60%;
.title{
padding: 13px;
display: flex;
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-01 09:55:12
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-12 11:15:21
* @LastEditTime: 2024-08-13 15:48:06
* @Version: 1.0.0
* @Description: 动态渲染-开关组件
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -16,6 +16,7 @@
<div class="d-form-item">
<van-field
:name="name"
:disabled="disabled"
:required="required"
:rules="[{ required, message: `请填写${label}` }]"
......@@ -41,6 +42,10 @@ export default {
DLabel
},
props: {
name: {
type: String,
default: ''
},
help: {
type: String,
default: ''
......
......@@ -2,25 +2,31 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-29 10:51:56
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-12 14:09:34
* @LastEditTime: 2024-08-14 09:21:52
* @Version: 1.0.0
* @Description: 表单渲染
* @Copyright: Copyright (c) 2021, Hand-RongJing
-->
<template>
<fragment>
<DTitle v-if="showTitle" :title="tabInfo.description" :tabButtons="tabInfo.tabButtons || []" />
<DTitle
v-if="formType === 'normal'"
:title="tabInfo.description"
:tabButtons="tabInfo.tabButtons || []"
:showBtns="!readOnly"
/>
<van-form ref="formRef" error-message-align="right" input-align="right">
<fragment v-for="field in fieldList" :key="field.columnName">
<d-field
v-if="fieldComponents.indexOf(field.validationTypeDisplay) > -1"
v-model="fieldsObj[field.columnName]"
v-model="fieldsObj[field.columnName]"
:name="field.columnName"
:fieldConfig="field"
:type="field.validationTypeDisplay"
:help="field.help"
:label="field.description"
:disabled="field.readOnly"
:disabled="readOnly || field.readOnly"
:required="field.required"
:clearable="field.clearFlag"
/>
......@@ -29,8 +35,9 @@
v-if="field.validationTypeDisplay === 'Switch'"
:label="field.description"
:help="field.help"
:name="field.columnName"
v-model="fieldsObj[field.columnName]"
:disabled="field.readOnly"
:disabled="readOnly || field.readOnly"
:required="field.required"
@change="fieldChange"
/>
......@@ -39,8 +46,9 @@
v-if="field.validationTypeDisplay === 'CheckBox' || field.validationTypeDisplay === 'Radio'"
:label="field.description"
:help="field.help"
:name="field.columnName"
v-model="fieldsObj[field.columnName]"
:disabled="field.readOnly"
:disabled="readOnly || field.readOnly"
:required="field.required"
@change="fieldChange"
/>
......@@ -49,23 +57,26 @@
v-if="field.validationTypeDisplay === 'Select'"
v-model="fieldsObj[field.columnName]"
:help="field.help"
:name="field.columnName"
:label="field.description"
:fieldConfig="field"
:disabled="field.readOnly"
:disabled="readOnly || field.readOnly"
:required="field.required"
:clearable="field.clearFlag"
:multiple="field.multiple === 1"
:cascadesParams="getCascadesParams(field)"
@change="fieldChange"
/>
<d-lov
v-if="field.validationTypeDisplay === 'Lov'"
v-model="fieldsObj[field.columnName]"
:name="field.columnName"
:record="fieldsObj"
:help="field.help"
:label="field.description"
:fieldConfig="field"
:disabled="field.readOnly"
:disabled="readOnly || field.readOnly"
:required="field.required"
:clearable="field.clearFlag"
:cascadesParams="getCascadesParams(field)"
......@@ -76,20 +87,22 @@
<d-date
v-if="dateComponents.indexOf(field.validationTypeDisplay) > -1"
v-model="fieldsObj[field.columnName]"
:name="field.columnName"
:label="field.description"
:help="field.help"
:fieldConfig="field"
:disabled="field.readOnly"
:disabled="readOnly || field.readOnly"
:required="field.required"
:clearable="field.clearFlag"
/>
<d-url
v-if="field.validationTypeDisplay === 'UrlField'"
:name="field.columnName"
:label="field.description"
:help="field.help"
v-model="fieldsObj[field.columnName]"
:disabled="field.readOnly"
:disabled="readOnly || field.readOnly"
:required="field.required"
@change="fieldChange"
/>
......@@ -108,7 +121,6 @@ import DDate from './FormItem/DDate';
import DCheckbox from './FormItem/DCheckbox';
import DUrl from './FormItem/DUrl';
import DTitle from '../DTitle';
import DButtons from '../DButtons';
import hlsHttp from '../../utils/hlsHttp';
export default {
......@@ -126,7 +138,6 @@ export default {
DCheckbox,
DUrl,
DTitle,
DButtons,
DCheckbox
},
props: {
......@@ -136,7 +147,7 @@ export default {
},
formType: {
type: String,
default: 'normal', // normal:正常表单, query: 查询表单
default: 'normal', // normal:正常表单, query: 查询表单, tableForm: 表格详情表单
},
showTitle: {
type: Boolean,
......@@ -162,20 +173,25 @@ export default {
componentTypes: ["UrlField"],
fieldList: [...this.fields],
fieldsObj: {},
originFieldsObj: {}, // 重置使用
queryParams: {},
readOnly: true,
status: 'add',
}
},
inject: ['dynamicInfo'],
inject: ['dynamicInfo', 'addFormRef', 'setDataSetData'],
mounted() {
console.log('D-form', this.fields)
this.init();
},
activated() {
console.log('D-form', this.fields)
console.log('D-form-activated', this.fields)
this.init();
},
methods: {
init() {
async init() {
this.queryParams = this.dynamicInfo().queryParams;
this.readOnly = this.queryParams.readOnly;
if (JSON.stringify(this.record) === '{}') { // 新建
let initFields = {}
this.fields.forEach(item => {
......@@ -185,14 +201,44 @@ export default {
}
})
this.fieldsObj = {...initFields};
this.status = 'add';
} else { // 详情
this.fieldsObj = {...this.record};
this.status = 'update';
}
if (this.tabInfo && this.tabInfo.readUrl) {
hlsHttp.get(this.tabInfo.readUrl, this.queryParams).then(res => {
if (this.formType === 'normal') {
if (this.tabInfo.readUrl) {
const res = await hlsHttp.get(this.tabInfo.readUrl, this.queryParams)
this.fieldsObj = res.content.length ? res.content[0] : {};
})
this.addFormRef(this, this.tabInfo.tabCode); //正常表单保存表单组件实例,供页面整体保存时使用
this.setDataSetData(this.tabInfo.tabCode, {...this.fieldsObj}); // 保存一份原始数据
this.status = 'update';
} else {
this.status = 'add';
}
}
this.formatFieldsValue();
},
formatFieldsValue() {
this.originFields.forEach(item => {
if (item.bind && this.fieldsObj[item.columnName]) { // 主要处理lov绑定字段
const bindField = item.bind.split('.');
if (bindField.length >1) {
if (this.fieldsObj[bindField[0]]) {
this.fieldsObj[bindField[0]][bindField[1]] = this.fieldsObj[item.columnName];
} else {
this.fieldsObj[bindField[0]] = {
[bindField[1]]: this.fieldsObj[item.columnName]
};
}
} else {
this.fieldsObj[bindField[0]] = this.fieldsObj[item.columnName];
}
}
})
this.originFieldsObj = {...this.fieldsObj};
console.log('this.fieldsObj', this.fieldsObj)
},
getInputType(type) {
if (type === 'TextArea') {
......@@ -229,22 +275,37 @@ export default {
// console.log(val)
},
validate() {
this.$refs.formRef.submit();
const values = {...this.fieldsObj};
this.originFields.forEach(item => {
if (item.bind) {
const bindField = item.bind.split('.');
if (bindField.length >1) {
values[item.columnName] = values[bindField[0]] ? values[bindField[0]][bindField[1]] : undefined;
} else {
values[item.columnName] = values[bindField[0]];
return new Promise((resolve, rejcet) => {
this.$refs.formRef.validate().then(() => {
const values = {...this.fieldsObj};
console.log('values', values)
const formValues = {};
this.originFields.forEach(item => {
if (item.bind) {
const bindField = item.bind.split('.');
if (bindField.length >1) {
values[item.columnName] = values[bindField[0]] ? values[bindField[0]][bindField[1]] : values[item.columnName];
} else {
values[item.columnName] = values[bindField[0]] || values[item.columnName];
}
}
if (item.dataType === 'boolean') {
values[item.columnName] = values[item.columnName] ? 1 : 0;
}
formValues[item.columnName] = values[item.columnName];
});
const result = {
allValues: {...values, _status: this.status}, // 完整的数据,包含record或者接口查询的所有字段信息
formValues: {...formValues, _status: this.status} // 只包含配置的fileds信息
}
}
if (item.dataType === 'boolean') {
values[item.columnName] = values[item.columnName] ? 1 : 0;
}
})
return values;
resolve(result);
}).catch(errors => {
rejcet(errors);
});
});
},
reset() {
this.fieldsObj = {...this.originFieldsObj};
}
},
}
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-30 09:41:54
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-11 10:28:01
* @LastEditTime: 2024-08-12 16:12:51
* @Version: 1.0.0
* @Description: 表格列渲染
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -24,20 +24,31 @@ const DTableTd = {
tdRender: {
type: Function,
default: null
},
typeDisplay: {
type: String,
default: 'Field'
}
},
data () {
return {
}
},
methods: {
columnValue() {
if (['Lov', 'Select'].includes(this.typeDisplay)) {
return this.record[`${this.columnName}Name`];
} else {
return this.record[this.columnName];
}
}
},
// 为了弥补缺少的实例
// 提供第二个参数作为上下文
render: function (h, context) {
return this.tdRender ? this.tdRender(this.record) : <span>{this.$slots.default || (this.record[this.columnName] || '--')}</span>
return this.tdRender ?
this.tdRender(this.record) :
<span>{this.$slots.default || (this.columnValue() || '--')}</span>
}
};
......
......@@ -2,14 +2,19 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-29 10:51:56
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-12 14:10:34
* @LastEditTime: 2024-08-14 09:16:29
* @Version: 1.0.0
* @Description: 表格渲染
* @Copyright: Copyright (c) 2021, Hand-RongJing
-->
<template>
<fragment>
<DTitle :title="tabInfo.description" :tabButtons="tabInfo.tabButtons || []" :buttonsFun="buttonsClick" />
<DTitle
:title="tabInfo.description"
:tabButtons="tabInfo.tabButtons || []"
:buttonsFun="buttonsClick"
:showBtns="!readOnly"
/>
<scroll
ref="scroll" :pullUp="true" :pull-down="true" @pullingUp="getList"
......@@ -27,7 +32,7 @@
:columnName="column.columnName"
:record="item" />
</van-checkbox>
<van-icon name="records-o" @click="showRecord(item, pIndex)"/>
<van-icon name="records-o" v-if="showEdit" @click="showRecord(item, pIndex)"/>
</div>
<div v-else class="d-table-tr">
<span>{{column.description}}</span>
......@@ -35,6 +40,7 @@
:tdRender="column.renderer"
:columnName="column.columnName"
:record="item"
:typeDisplay="column.validationTypeDisplay"
>
<template v-if="booleanType.includes(column.validationTypeDisplay)">
{{booleanDisplay[item[column.columnName]] || '--'}}
......@@ -54,7 +60,7 @@
:originFields="originColumns"
ref="dformRef"
:record="record"
:showTitle="false"
formType="tableForm"
/>
</div>
<div class="d-table-form-footer">
......@@ -81,6 +87,7 @@ import DTableTd from './DTableTd.jsx';
import { Checkbox, CheckboxGroup, Popup, Button, Icon, Toast } from 'vant';
import hlsHttp from '../../utils/hlsHttp';
import {getDataSetName, getOrganizationId} from '../../utils/utils';
import EventBus from '../../utils/eventBus';
export default {
name: 'DTable',
......@@ -123,9 +130,12 @@ export default {
},
page: 0,
size: 10,
queryParams: {},
tableData: [], // 表格数据
checkResult: [],
visible: false,
showEdit: false,
readOnly: true,
record: {}, // 操作记录
recordIndex: -1,
buttonsFun: {},
......@@ -140,8 +150,33 @@ export default {
this.dynamicConfigInfo = this.dynamicInfo();
this.init();
},
deactivated() {
EventBus.$off('tableQuery');
},
beforeDestroy() {
EventBus.$off('tableQuery');
},
methods: {
init() {
if (this.tabInfo.queryTabCode) {
EventBus.$on('tableQuery', (data, queryTabCode) => {
if (this.tabInfo.queryTabCode === queryTabCode) {
this.queryParams = data;
this.refresh();
}
});
}
this.refresh();
this.readOnly = this.dynamicConfigInfo.queryParams.readOnly;
// 设置是否可以编辑
if (this.dynamicConfigInfo.queryParams.readOnly) {
this.showEdit = false;
} else {
this.showEdit = this.columns.some(o => !o.readOnly); // 存在可输入则显示编辑
}
},
refresh() {
this.page = 0;
this.tableData = [];
this.getList();
......@@ -151,6 +186,7 @@ export default {
const params = {
page: this.page,
size: this.size,
...this.queryParams,
...this.dynamicConfigInfo.queryParams,
}
hlsHttp.get(this.tabInfo.readUrl, params).then(res => {
......@@ -165,12 +201,21 @@ export default {
},
showRecord(res, index) {
this.record = {...res};
this.recordIndex = index;
this.visible = true;
this.recordIndex = index;
this.visible = true;
// if (this.tabInfo.createUrl) {
// this.record = {...res};
// this.recordIndex = index;
// this.visible = true;
// console.log('this.record', this.record)
// } else {
// Toast.fail('保存接口未配置,请检查配置');
// }
},
saveRecord() {
const values = this.$refs.dformRef.validate();
hlsHttp.post(this.tabInfo.createUrl, [{...values, ...this.dynamicConfigInfo.queryParams}]).then(() => {
async saveRecord() {
const {allValues} = await this.$refs.dformRef.validate();
hlsHttp.post(this.tabInfo.createUrl, [{...allValues, ...this.dynamicConfigInfo.queryParams}]).then(() => {
this.visible = false;
Toast.success('保存成功!');
this.init();
......@@ -182,7 +227,7 @@ export default {
// 删除
deleteRecords() {
let result = this.tableData.filter(o => this.checkResult.includes(o[this.tabInfo.primaryKey]));
const dataSetName = getDataSetName(this.dynamicConfigInfo.config, this.tabInfo.tabCode);
const dataSetName = getDataSetName(this.dynamicConfigInfo.dataSetObject, this.tabInfo.tabCode);
const url = this.tabInfo.destroyUrl ||
`/hllc/v1/${getOrganizationId()}/dynamic-crud/delete${dataSetName ? '?datasetName=' + dataSetName : ''}`;
hlsHttp.delete(url , result).then(res=> {
......@@ -193,11 +238,7 @@ export default {
buttonsClick(btn) {
switch (btn.name) {
case 'create':
if (this.tabInfo.createUrl) {
this.showRecord({}, -1);
} else {
Toast.fail('保存接口未配置,请检查配置');
}
this.showRecord({}, -1);
break;
case 'query':
console.log('查询')
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-02 15:32:36
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-09 10:16:37
* @LastEditTime: 2024-08-14 09:19:09
* @Version: 1.0.0
* @Description: 组件头部渲染
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -10,7 +10,7 @@
<template>
<div class="layout-title">
<div class="title">{{title}}</div>
<div class="title-btns">
<div class="title-btns" v-if="showBtns">
<van-button
v-for="btn in defaultBtns"
round
......@@ -40,7 +40,6 @@
<script>
import { Button, Icon, Popover } from 'vant';
import DButtons from '../DButtons';
export default {
name: 'DTitle',
......@@ -48,7 +47,6 @@ export default {
[Icon.name]: Icon,
[Button.name]: Button,
[Popover.name]: Popover,
DButtons
},
props: {
title: {
......@@ -62,7 +60,12 @@ export default {
buttonsFun: {
type: Function,
default: () => {}
},
showBtns: {
type: Boolean,
default: false,
}
},
data () {
return {
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-30 21:21:37
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-11 10:52:17
* @LastEditTime: 2024-08-13 16:41:48
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -534,7 +534,8 @@ class BaseComponentBuilder extends BaseBuilder {
buttons: this.buttons,
columns: this.columns.fields,
originColumns: this.columns._originFields
}
},
ref:`DTABLE_${this.tabCode}`,
},
[]
);
......@@ -578,7 +579,8 @@ class BaseComponentBuilder extends BaseBuilder {
fields: newFields.fields,
originFields: newFields._originFields,
tabInfo: this.props,
}
},
ref:`DFORM_${this.tabCode}`,
}
);
} else { // 查询组件
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-29 10:51:56
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-11 10:51:32
* @LastEditTime: 2024-08-13 17:52:35
* @Version: 1.0.0
* @Description: 查询表单渲染
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -22,24 +22,30 @@
</template>
</van-search>
<van-popup v-model="show" position="top">
<DForm :fields="fields" :originFields="originFields" ref="dformRef" formType="query" :showTitle="false" />
<div style="margin: 16px;">
<h-button
type="primary"
<van-popup v-model="show" position="top" class="query-form-popup">
<div class="query-form">
<DForm :fields="fields" :originFields="originFields" ref="dformRef" formType="query" :showTitle="false" />
</div>
<div class="query-form-btn">
<van-button
type="info"
v-for="btn in (tabInfo.tabButtons || [])"
:key="btn.name"
style="margin-left: 10px"
round
:plain="btn.name !== 'query'"
@click.native="btnFun(btn)"
>{{btn.description}}</h-button>
>{{btn.description}}</van-button>
</div>
</van-popup>
</div>
</template>
<script>
import { Search, Icon, Popup } from 'vant';
import { Search, Icon, Popup, Button } from 'vant';
import DForm from '../DForm';
import EventBus from '../../utils/eventBus';
import { isNull, isUndefined } from '../../../../packages';
export default {
name: 'QueryForm',
......@@ -47,7 +53,8 @@ export default {
DForm,
[Search.name]: Search,
[Icon.name]: Icon,
[Popup.name]: Popup
[Popup.name]: Popup,
[Button.name]: Button,
},
props: {
fields: {
......@@ -69,11 +76,10 @@ export default {
searchValue: '',
}
},
inject: ['config'],
inject: ['dynamicInfo'],
mounted() {
this.configDatas = this.config();
console.log('query-form', this.fields)
this.configDatas = this.dynamicInfo().config;
},
methods: {
onSearch() { // 搜索
......@@ -83,15 +89,48 @@ export default {
this.show = true;
},
btnFun(btn) {
console.log('过来了吗', this.$refs.dformRef)
this.$refs.dformRef.validate();
if (btn.name === 'query') {
this.query();
} else if (btn.name === 'reset') {
this.reset();
}
},
async query() {
const {formValues} = await this.$refs.dformRef.validate();
let values = {};
Object.keys(formValues).forEach(key => {
if (!isNull(formValues[key]) && !isUndefined(formValues[key]) && formValues[key] !== '') {
values[key] = formValues[key];
}
});
EventBus.$emit('tableQuery', values, this.tabInfo.tabCode);
this.show = false;
},
reset() {
this.$refs.dformRef.reset()
}
},
}
</script>
<style scoped lang="less">
.content{
//background-color: #cfcfcf;
}
.query-form-popup {
max-height: 60%;
display: flex;
flex-direction: column;
overflow: hidden;
.query-form {
overflow: auto;
height: calc(100% - 50px);
}
.query-form-btn {
display: flex;
align-items: center;
padding: 10px;
.van-button {
flex: 1;
}
}
}
</style>
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-30 09:41:54
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-11 11:08:27
* @LastEditTime: 2024-08-13 16:43:34
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -54,6 +54,7 @@ const ConfigRenderComponent = {
mounted() {
this.configInfo = this.dynamicInfo().config;
console.log('this.componentRenderers', this.componentRenderers, this.dynamicInfo())
console.log(this.$refs);
},
activated () {
......@@ -136,14 +137,6 @@ const ConfigRenderComponent = {
}
const Layout = this.getLayout(layoutName);
return <Layout componentNames={componentNames} components={components}/>
// return new LayoutBuilder()
// .withLayout(this.getLayout(layoutName))
// .withTabCode(layoutTab.tabCode)
// // .withTabMap(tabMap)
// .withComponents(components)
// .withComponentNames(componentNames)
// // .withComponentFunctions(componentFunctions)
// .build();
});
},
getLayout(layoutName) {
......
......@@ -2,13 +2,13 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-31 15:09:30
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-09 17:44:54
* @LastEditTime: 2024-08-14 09:14:38
* @Version: 1.0.0
* @Description: 页面按钮渲染
* @Copyright: Copyright (c) 2021, Hand-RongJing
-->
<template>
<div class="layout-buttons" :id="id">
<div class="layout-buttons" :id="id" v-if="!readOnly && layoutButtons.length">
<van-popover
v-if="layoutButtons.length > num"
v-model="moreVisible"
......@@ -45,8 +45,10 @@
</template>
<script>
import { Button, Icon, Popover } from 'vant';
import { Button, Icon, Popover, Toast } from 'vant';
import { v4 as uuidv4 } from 'uuid';
import hlsHttp from '../utils/hlsHttp';
import { getOrganizationId } from '../utils/utils';
export default {
name: 'LayoutButtons',
......@@ -54,8 +56,15 @@ export default {
[Button.name]: Button,
[Icon.name]: Icon,
[Popover.name]: Popover,
[Toast.name]: Toast,
},
inject: ['dynamicInfo'],
props: {
parentContext: { // 是否需要返回键
type: Object,
default: () => ({})
},
},
inject: ['config'],
data () {
return {
id: 'layoutButton' + uuidv4(),
......@@ -64,6 +73,7 @@ export default {
num: 2,
defaultBtns: [],
hideBtns: [],
readOnly: true,
moreVisible: false,
buttonIcon: {
create: 'plus',
......@@ -75,21 +85,12 @@ export default {
}
},
mounted() {
this.configInfo = this.config();
this.configInfo = this.dynamicInfo().config;
this.readOnly = this.dynamicInfo().queryParams.readOnly;
this.layoutButtons = this.configInfo.layoutButtons || [];
// document.addEventListener('click', this.clickEle, false)
this.init();
},
destroyed () {
// document.removeEventListener('click', this.clickEle, false)
},
methods: {
// clickEle (e) {
// let content = document.querySelector('.layout-buttons-more')
// if ((content && !content.contains(e.target))) {
// this.moreVisible = false;
// }
// },
init() {
if(this.layoutButtons.length > this.num) {
this.defaultBtns = this.layoutButtons.slice(0, this.num);
......@@ -98,14 +99,86 @@ export default {
this.defaultBtns = [...this.layoutButtons];
}
},
// more() {
// this.moreVisible = true;
// },
handlClick(btn) {
this.moreVisible = false;
console.log(btn.name)
}
},
if (btn.name === 'save') {
this.saveFunction();
}
},
async saveFunction() {
const saveDataSet = this.dynamicInfo().dataSetObject;
const dataSets = {...saveDataSet};
for (let key in dataSets) {
if (dataSets.hasOwnProperty(key)) { // 确保key是对象自身的属性
const {formRef} = dataSets[key];
if(formRef) {
const values = await formRef.validate();
dataSets[key].submitValues = values;
}
}
}
const {layoutCode, metaKeys, dataSetMap} = this.getDataSets(dataSets);
hlsHttp.post(`/hllc/v1/${getOrganizationId()}/dynamic-crud/save`, [{
layoutCode, metaKeys, ...dataSetMap
}]).then(res => {
Toast.success('保存成功!');
})
},
getDataSets(dataSetTree) {
const { layoutCode } = this.dynamicInfo().config;
const metaKeys = { top: [] };
const dataSetMap = {};
const serverNames = {};
const saveCheckUrls = {};
const delChackUrls = {};
Object.values(dataSetTree).forEach(config => {
const { parentDataSetName, dataSetName, baseTable, parentTable, submitValues, savedCheckApi } = config;
if (baseTable !== parentTable) { // 不是同一数据源
if (parentDataSetName) {
if (dataSetMap[parentDataSetName]) { // 存在值
let currentVal = dataSetMap[parentDataSetName][0];
currentVal[dataSetName] = submitValues ? [submitValues.allValues] : [];
dataSetMap[parentDataSetName] = [currentVal];
} else {
dataSetMap[parentDataSetName] = [{
[dataSetName]: submitValues ? [submitValues.allValues] : []
}]
}
metaKeys[parentDataSetName].push(dataSetName);
metaKeys[dataSetName] = [];
} else {
if (dataSetMap[dataSetName]) { // 存在值
let currentVal = dataSetMap[dataSetName][0];
currentVal = {...(submitValues ? submitValues.allValues : {}), ...currentVal};
if (currentVal.childrenDs) {
const childs = [...currentVal.childrenDs];
delete currentVal.childrenDs;
childs.forEach(item => {
currentVal = {...currentVal, ...item};
})
}
dataSetMap[dataSetName] = [currentVal];
} else {
dataSetMap[dataSetName] = submitValues ? [submitValues.allValues] : []
}
metaKeys.top.push(dataSetName);
metaKeys[dataSetName] = [];
}
} else if (baseTable) { // 复用数据源
if (dataSetMap[parentDataSetName]) {
let currentVal = dataSetMap[parentDataSetName][0];
dataSetMap[parentDataSetName] = [{...currentVal, ...(submitValues ? submitValues.formValues : {})}];
} else {
dataSetMap[parentDataSetName] = [{childrenDs: submitValues ? submitValues.formValues : {}}]
}
}
});
return {
layoutCode, metaKeys, dataSetMap, serverNames, saveCheckUrls, delChackUrls
}
},
}
}
</script>
......@@ -125,6 +198,7 @@ export default {
font-family: PingFangSC-Semibold;
font-size: 16px;
font-weight: 600;
flex: 1;
}
.layout-button-more {
color: #666666;
......@@ -154,6 +228,7 @@ export default {
box-shadow: 0px 0px 18px 0px rgba(0,0,0,0.2);
border-radius: 20px;
white-space: nowrap;
padding: 8px;
// margin: 6px 0;
// box-shadow: 0px 2px 2px 0px #3789ff;
}
......
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-29 10:51:56
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-12 09:31:49
* @LastEditTime: 2024-08-13 13:02:20
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -21,7 +21,7 @@
:componentRenderers="componentRenderers"
/>
</h-content>
<layout-buttons v-if="configDatas.id" />
<layout-buttons v-if="configDatas.id"/>
</h-view>
</template>
......@@ -31,6 +31,8 @@ import LayoutButtons from './LayoutButtons';
import ConfigRenderComponent from './ConfigRenderComponent/index.jsx';
import {query, queryRoute} from './service'
import './index.less'
import { getOrganizationId } from './utils/utils';
import Constants from './utils/Constants';
export default {
name: 'Dynamic',
......@@ -58,42 +60,38 @@ export default {
loading: false,
queryParams: {}, // 查询参数
qpara: {},
configDatas: {},
params: {},
config: {
datas: {},
params: {}
},
configDatas: {}, // 页面配置信息
params: {}, // 页面路由参数
dataSetObject: {}, // 页面配置信息的dataset
duplicateDs: {}
}
},
provide() {
return {
config: () => this.configDatas, // 提供方法,注意提供的方法要写在return对象中
queryParams: () => this.queryParams,
addFormRef: this.addFormRef,
setDataSetData: this.setDataSetData,
dynamicInfo: () => ({ // 配置的所有信息
layoutCode: this.layoutCode,
config: this.configDatas,
queryParams: {
...this.$route.params,
...this.$route.query
},
dataSetObject: this.dataSetObject,
queryParams: this.qpara,
componentRenderers: this.componentRenderers
})
};
},
created() {
window.localStorage.setItem('access_token', '1f22ae78-2ee2-470c-bea4-916396e5632c');
this.queryParams = {
window.localStorage.setItem('access_token', '5d974657-7d25-4a4a-8195-6266f308a863');
this.params = {
...this.$route.params,
...this.$route.query
}
},
activated() {
this.queryParams = {
this.params = {
...this.$route.params,
...this.$route.query
}
console.log('activated', this.queryParams)
console.log('activated', this.params)
},
beforeMount() {
this.layoutCodeQuery();
......@@ -105,14 +103,14 @@ export default {
this.loading = true;
let readOnly = false
// eslint-disable-next-line eqeqeq
if (this.queryParams.readOnly === "YES" || this.queryParams.readOnly == 'true') {
if (this.params.readOnly === "YES" || this.params.readOnly == 'true') {
readOnly = true
}
// if (disabled) {
// readOnly = disabled
// }
this.qpara = {
...this.queryParams,
...this.params,
readOnly,
};
// if (this.store.config.datas !== null && isEqual(this.qpara, this.store.config.param)) {
......@@ -124,10 +122,11 @@ export default {
} else {
res = await queryRoute(this.layoutCode, this.qpara);
}
const dataSetObj = this.transformDateSetTree(res.datas.dataSetsTree);
this.configDatas = {...res.datas, dataSetObject: dataSetObj};
this.params = res.params;
this.loading = false;
this.configDatas = {...res.datas};
this.params = res.params;
this.dataSetObject = this.transformDateSetTree(res.datas.dataSetsTree);
// this.getDataSets(res.datas.dataSetsTree)
},
transformDateSetTree(tree) {
let obj = {};
......@@ -139,13 +138,17 @@ export default {
})
}
return obj;
}
},
addFormRef(ref, tabCode) { // 添加表单实例
this.dataSetObject[tabCode].formRef = ref;
},
setDataSetData(tabCode, data) {
this.dataSetObject[tabCode].data = data;
},
},
}
</script>
<style scoped lang="less">
.content{
//background-color: #cfcfcf;
}
</style>
/*
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-13 17:18:28
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-13 17:20:54
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
*/
import Vue from 'vue';
const EventBus = new Vue();
export default EventBus;
\ No newline at end of file
......@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-30 14:39:47
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-11 15:27:32
* @LastEditTime: 2024-08-13 16:10:43
* @Version: 1.0.0
* @Description: 工具类
* @Copyright: Copyright (c) 2021, Hand-RongJing
......@@ -30,7 +30,7 @@ const getHeaderExtrasProp = (layoutCode, tabCode, props) => {
};
const getDataSetName = (config, tabCode) => {
return config.dataSetObject[tabCode].dataSetName || '';
return config[tabCode].dataSetName || '';
};
/**
......
......@@ -2,14 +2,14 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-31 18:41:49
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-07-31 18:53:12
* @LastEditTime: 2024-08-13 10:47:38
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
-->
<template>
<Dynamic layoutCode="BP001F1" />
<Dynamic layoutCode="PRJ005F1" />
</template>
<script>
......
<!--
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-29 11:02:22
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-13 10:51:44
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
-->
<template>
<Dynamic layoutCode="BP001" :componentRenderers="componentRenderers" />
<Dynamic layoutCode="PRJ005" :componentRenderers="componentRenderers" />
</template>
<script>
......@@ -16,9 +25,9 @@ export default {
componentRenderers: [
{
tabCode: 'G_QUERY_RESULT',
columnName: 'bpName',
columnName: 'projectName',
renderer: (record) => {
return <span style="color: #3789ff" onClick={() => this.toDetail(record)}>{record.bpName} <van-icon name="arrow" /></span>
return <span style="color: #3789ff" onClick={() => this.toDetail(record)}>{record.projectName} <van-icon name="arrow" /></span>
},
},
]
......@@ -26,19 +35,20 @@ export default {
},
methods: {
toDetail(record) {
console.log({
bpId: record.bpId,
bpName: record.bpName,
bpCode: record.bpCode,
})
this.$router.push({
this.$router.push({
name: 'DynamicDetail',
params: {
bpId: record.bpId,
bpName: record.bpName,
bpCode: record.bpCode,
projectId: record.projectId
}
})
// this.$router.push({
// name: 'DynamicDetail',
// params: {
// bpId: record.bpId,
// bpName: record.bpName,
// bpCode: record.bpCode,
// }
// })
},
},
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment