Browse Source
2、表格组件增加本地模式。 3、表格组件cell选择模式下双击编辑失效。 4、表格组件内容区域编辑增加单元格编辑模式,同时增加单元格弹窗编辑。 5、表格组件增加内联单元格编辑、内联行编辑等。 6、表格组件修复多行表头右边框丢失问题。 7、表格组件修复无数据时出现双重下边框问题。 7、表格组件增加行数据自动合并功能。 8、w-number组件调整为默认可输入小数且不控制精度,可设置精度。 9、增加w-integer组件,只可以输入整数类型的数据。main
17 changed files with 836 additions and 258 deletions
@ -0,0 +1,144 @@ |
|||||
|
<template> |
||||
|
<w-dialog ref="dialogRef" :title="dialog.title" v-bind="props.grid.props.editor?.cellEditor" :buttons="dialog.buttons"> |
||||
|
<w-form ref="dialogFormRef" :cols-num="1" :fields="fieldsComputed" class="pt-1.5 px-1.5"></w-form> |
||||
|
</w-dialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, reactive, inject, computed, toRaw } from 'vue'; |
||||
|
import { t, Tools, noErrorAxios, NotifyManager } from '@/platform'; |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
const dialogFormRef = ref(); |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
grid: { |
||||
|
// 表格实例 |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
url: { |
||||
|
// 表格所有的url |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
getRow: { |
||||
|
type: Function, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
componentInfo: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
}, |
||||
|
}, |
||||
|
rowKeyName: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
}); |
||||
|
const table = inject('table'); |
||||
|
|
||||
|
const dialog = { |
||||
|
title: t('action.edit'), |
||||
|
buttons: [ |
||||
|
{ |
||||
|
icon: 'beenhere', |
||||
|
labelI18nKey: 'action.submit', |
||||
|
label: t('action.submit'), |
||||
|
loading: false, |
||||
|
click: async () => { |
||||
|
dialog.buttons[0].loading = true; |
||||
|
const result = await dialogFormRef.value.validate(); |
||||
|
if (result) { |
||||
|
const cellSelected = table['cellSelected']; |
||||
|
const data = dialogFormRef.value.getData(); |
||||
|
const row = props.getRow(table.rows, cellSelected['row'][props.rowKeyName], false); |
||||
|
if (row) { |
||||
|
row[cellSelected['colName']] = data[cellSelected['colName']]; |
||||
|
// 判定是否需要往后端发送修改操作 |
||||
|
if (!props.grid.props.localMode) { |
||||
|
const requestParams = { |
||||
|
method: 'PUT', |
||||
|
headers: { 'content-type': 'application/json;charset=utf-8;' }, |
||||
|
data: toRaw(row), |
||||
|
url: getUrl(row[props.grid.props.primaryKey]), |
||||
|
}; |
||||
|
noErrorAxios(requestParams) |
||||
|
.then((resp) => { |
||||
|
dialog.buttons[0].loading = false; |
||||
|
props.grid.emit('afterEditorDataSubmit', { grid: props.grid, data: resp.data }); |
||||
|
NotifyManager.info(t('tip.operationSuccess')); |
||||
|
dialogRef.value.hide(); |
||||
|
}) |
||||
|
.catch((error) => { |
||||
|
const response = error?.response; |
||||
|
const status = response?.status; |
||||
|
const data = response?.data; |
||||
|
if (data?.code === 1001) { |
||||
|
// 验证错误 |
||||
|
if (error.response.data.data) { |
||||
|
dialogFormRef.value.setValidationErrors(error.response.data.data); |
||||
|
} |
||||
|
} else { |
||||
|
//其他错误 |
||||
|
if (status === 500) { |
||||
|
NotifyManager.error(t(data?.errorMessageI18nKey)); |
||||
|
} else { |
||||
|
NotifyManager.error(t(status)); |
||||
|
} |
||||
|
} |
||||
|
dialog.buttons[0].loading = false; |
||||
|
}); |
||||
|
} else { |
||||
|
dialogRef.value.hide(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
dialog.buttons[0].loading = false; |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
|
||||
|
const fieldsComputed = computed(() => { |
||||
|
const fields = <any>[]; |
||||
|
const cellSelected = table['cellSelected']; |
||||
|
if (Object.keys(cellSelected).length > 0) { |
||||
|
const column = table['columns'].find((item) => item['name'] === cellSelected['colName']); |
||||
|
if (column) { |
||||
|
fields.push({ |
||||
|
name: column['name'], |
||||
|
type: column['type'], |
||||
|
label: column['label'], |
||||
|
defaultValue: cellSelected['value'], |
||||
|
...column['attrs'], |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
return fields; |
||||
|
}); |
||||
|
|
||||
|
const getUrl = (primaryKey) => { |
||||
|
if (!Tools.isEmpty(props.url.editDataUrl)) { |
||||
|
return props.url.editDataUrl + '/' + primaryKey; |
||||
|
} else { |
||||
|
return props.url.dataUrl + '/' + primaryKey; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const getDialog = () => { |
||||
|
return dialogRef.value; |
||||
|
}; |
||||
|
const getForm = () => { |
||||
|
return dialogFormRef.value; |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
getDialog, |
||||
|
getForm, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,72 @@ |
|||||
|
<template> |
||||
|
<div v-show="fieldMethodsClass.getShow(props, modelValue)"> |
||||
|
<q-input |
||||
|
ref="numberRef" |
||||
|
v-model="modelValue" |
||||
|
:hide-bottom-space="true" |
||||
|
:hide-hint="true" |
||||
|
:outlined="true" |
||||
|
:dense="true" |
||||
|
v-bind="attrs" |
||||
|
type="number" |
||||
|
title="" |
||||
|
:rules="fieldMethodsClass.getRules(props, modelValue, numberRef, [FormValidators.maxPrecision(0)])" |
||||
|
:readonly="fieldMethodsClass.getReadOnly(props, modelValue)" |
||||
|
:disable="fieldMethodsClass.getDisable(props, modelValue)" |
||||
|
@update:model-value="fieldMethodsClass.updateValue" |
||||
|
> |
||||
|
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> |
||||
|
</q-input> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, useAttrs } from 'vue'; |
||||
|
import { FormValidators } from '@/platform/components'; |
||||
|
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; |
||||
|
import { FormFieldMethods } from '../form/FormField'; |
||||
|
|
||||
|
const numberRef = ref(); |
||||
|
const attrs = useAttrs(); |
||||
|
const modelValue = defineModel<number>(); |
||||
|
|
||||
|
interface FieldProps extends FormFieldProps {} |
||||
|
const props = withDefaults(defineProps<FieldProps>(), { showIf: true }); // 使用withDefaults设置属性默认值 |
||||
|
class FieldMethods extends FormFieldMethods { |
||||
|
// 继承FieldMethods抽象类,该类中包含必须实现的抽象方法并提供了一些获取计算后的是否必填,是否显示等静态方法 |
||||
|
updateValue = (value_) => { |
||||
|
const floatValue = parseInt(value_); |
||||
|
if (!isNaN(floatValue)) { |
||||
|
modelValue.value = floatValue; |
||||
|
if (props['onUpdateValue']) { |
||||
|
props['onUpdateValue']({ |
||||
|
value: floatValue, |
||||
|
form: props['form'], |
||||
|
}); |
||||
|
} |
||||
|
} else { |
||||
|
modelValue.value = undefined; |
||||
|
} |
||||
|
}; |
||||
|
validate = () => { |
||||
|
return numberRef.value.validate(); |
||||
|
}; |
||||
|
setValue = (value_) => { |
||||
|
modelValue.value = value_; |
||||
|
}; |
||||
|
getValue = () => { |
||||
|
return modelValue.value; |
||||
|
}; |
||||
|
clearValue = () => { |
||||
|
modelValue.value = undefined; |
||||
|
}; |
||||
|
} |
||||
|
const fieldMethodsClass = new FieldMethods(); |
||||
|
|
||||
|
// 暴露该组件的以下方法 |
||||
|
defineExpose({ |
||||
|
validate: fieldMethodsClass.validate, |
||||
|
setValue: fieldMethodsClass.setValue, |
||||
|
getValue: fieldMethodsClass.getValue, |
||||
|
clearValue: fieldMethodsClass.clearValue, |
||||
|
}); |
||||
|
</script> |
Loading…
Reference in new issue