Browse Source

🚨 简化地图任务处理

master
wangxiang 3 years ago
parent
commit
ed424af3d1
  1. 19
      src/components/AMap/src/amap.data.tsx
  2. 53
      src/components/AMap/src/components/MapTaskModal.vue
  3. 9
      src/components/AMap/src/components/MapTaskPresetModal.vue
  4. 200
      src/components/Table/src/components/editable/EditableCell.vue
  5. 30
      src/components/Table/src/types/table.ts

19
src/components/AMap/src/amap.data.tsx

@ -1,5 +1,4 @@ @@ -1,5 +1,4 @@
import { BasicColumn } from '/@/components/Table';
import { listHospital } from '/@/api/platform/common/controller/hospital';
import { listOrg } from '/@/api/platform/common/controller/org';
import { commonUpload } from '/@/api/platform/core/controller/upload';
import { h } from 'vue';
@ -50,7 +49,7 @@ export const operatePanelColumns: BasicColumn[] = [ @@ -50,7 +49,7 @@ export const operatePanelColumns: BasicColumn[] = [
];
/** 普通任务表格列 */
export const taskColumns: BasicColumn[] = [
export const taskOrdinaryColumns: BasicColumn[] = [
{
title: '任务名称',
dataIndex: 'name',
@ -63,14 +62,6 @@ export const taskColumns: BasicColumn[] = [ @@ -63,14 +62,6 @@ export const taskColumns: BasicColumn[] = [
editRow: true,
editRule: true,
editComponent: 'ApiSelect',
editComponentProps: {
style: { width:'100%' },
api: listHospital,
params: { size: 40, mapNotify: '1' },
labelField: 'name',
valueField: 'id',
resultField: 'data'
}
},
{
title: '医检',
@ -129,14 +120,6 @@ export const taskPresetColumns: BasicColumn[] = [ @@ -129,14 +120,6 @@ export const taskPresetColumns: BasicColumn[] = [
editRow: true,
editRule: true,
editComponent: 'ApiSelect',
editComponentProps: {
style: { width:'100%' },
api: listHospital,
params: { size: 40, mapNotify: '1' },
labelField: 'name',
valueField: 'id',
resultField: 'data'
}
},
{
title: '目的地预设点',

53
src/components/AMap/src/components/MapTaskModal.vue

@ -61,13 +61,14 @@ @@ -61,13 +61,14 @@
import { reactive, toRaw } from 'vue';
import {BasicModal, ModalProps, useModal, useModalInner} from '/@/components/Modal';
import { BasicTable, useTable, EditRecordRow, BasicColumn, ActionItem, TableAction } from '/@/components/Table';
import { taskColumns, taskPresetColumns } from '../amap.data';
import { taskOrdinaryColumns, taskPresetColumns } from '../amap.data';
import TaskPresetModal from './MapTaskPresetModal.vue';
import { buildUUID } from '/@/utils/uuid';
import { useMessage } from '/@/hooks/web/useMessage';
import {add, cloneDeep} from 'lodash-es';
import { defaultMapData } from '/@/enums/amapEnum';
import { MapLogistic } from '/@/api/platform/common/entity/mapLogistic';
import { listHospital } from '/@/api/platform/common/controller/hospital';
/** 类型规范统一声明定义区域 */
interface WindowState {
@ -88,21 +89,64 @@ @@ -88,21 +89,64 @@
state.mapData = data.mapData;
const props: Partial<ModalProps> = { confirmLoading: false };
props.title = '任务配置';
const taskOrdinaryUpdateColumns: BasicColumn[] = [
{
title: '医院',
dataIndex: 'hospitalId',
editRow: true,
editRule: true,
editComponent: 'ApiSelect',
editComponentProps: ({ text, record, column, index }) => ({
style: { width:'100%' },
api: listHospital,
params: { size: 40, mapNotify: '1' },
disabled: record.hospitalId == state.mapData.sendOrderId,
labelField: 'name',
valueField: 'id',
resultField: 'data'
})
},
],
taskPresetUpdateColumns: BasicColumn[] = [
{
title: '医院',
dataIndex: 'hospitalId',
editRow: true,
editRule: true,
editComponent: 'ApiSelect',
editComponentProps: ({ text, record, column, index }) => ({
style: { width:'100%' },
api: listHospital,
params: { size: 40, mapNotify: '1' },
disabled: record.hospitalId == state.mapData.sendOrderId,
labelField: 'name',
valueField: 'id',
resultField: 'data'
})
},
];
const mapTask = cloneDeep(state.mapData?.mapTask || []);
setTaskOrdinaryTableData(mapTask.filter(item => ~~item.taskType == 0));
setTaskPresetTableData(mapTask.filter(item => ~~item.taskType == 1));
// :
setTaskOrdinaryColumns(taskOrdinaryColumns.map(item =>
taskOrdinaryUpdateColumns.find(e => e.dataIndex == item.dataIndex) || item
));
setTaskPresetColumns(taskPresetColumns.map(item =>
taskPresetUpdateColumns.find(e => e.dataIndex == item.dataIndex) || item
));
setModalProps(props);
});
const { notification } = useMessage();
const [taskPresetRegisterModal, { openModal }] = useModal();
const [taskOrdinaryRegisterTable, {
getDataSource: getTaskOrdinaryDataSource,
setTableData: setTaskOrdinaryTableData
setTableData: setTaskOrdinaryTableData,
setColumns: setTaskOrdinaryColumns
}] = useTable({
rowKey: 'id',
title: '普通任务',
columns: taskColumns,
columns: taskOrdinaryColumns,
pagination: {
pageSize: 4,
showSizeChanger: false
@ -122,7 +166,8 @@ @@ -122,7 +166,8 @@
});
const [taskPresetRegisterTable, {
getDataSource: getTaskPresetDataSource,
setTableData: setTaskPresetTableData
setTableData: setTaskPresetTableData,
setColumns: setTaskPresetColumns
}] = useTable({
rowKey: 'id',
title: '交接任务',

9
src/components/AMap/src/components/MapTaskPresetModal.vue

@ -115,15 +115,14 @@ @@ -115,15 +115,14 @@
}));
});
await listUser({ size: 40, userType: '1' }).then(res => {
columns[0].editComponentProps!.options = res.data?.map(item => ({
columns[0].editComponentProps.options = res.data?.map(item => ({
value: item.id,
label: item.nickName,
})).filter(item => item.value != state.courierUserId);
});
setColumns(taskPresetChildColumns.map(item => {
const column = columns.find(e => e.dataIndex == item.dataIndex);
return column ? column : item;
}));
setColumns(taskPresetChildColumns.map(item =>
columns.find(e => e.dataIndex == item.dataIndex) || item
));
const mapTaskPresetData = cloneDeep(state.taskPresetRow?.mapTaskPreset || []);
//
const lastElement = mapTaskPresetData[mapTaskPresetData.length - 1];

200
src/components/Table/src/components/editable/EditableCell.vue

@ -1,57 +1,26 @@ @@ -1,57 +1,26 @@
<template>
<div :class="prefixCls">
<div
v-show="!isEdit"
:class="{ [`${prefixCls}__normal`]: true, 'ellipsis-cell': column.ellipsis }"
@click="handleEdit"
>
<div class="cell-content" :title="column.ellipsis ? getValues ?? '' : ''">{{
getValues ?? '&nbsp;'
}}</div>
<FormOutlined v-if="!column.editRow" :class="`${prefixCls}__normal-icon`"/>
</div>
<div v-if="isEdit" v-click-outside="onClickOutside" :class="`${prefixCls}__wrapper`">
<CellComponent
v-bind="getComponentProps"
ref="elRef"
:component="getComponent"
:style="getWrapperStyle"
:popoverVisible="getRuleVisible"
:rule="getRule"
:ruleMessage="ruleMessage"
:class="getWrapperClass"
size="small"
@change="handleChange"
@options-change="handleOptionsChange"
@pressEnter="handleEnter"
/>
<div v-if="!getRowEditable" :class="`${prefixCls}__action`">
<CheckOutlined :class="[`${prefixCls}__icon`, 'mx-2']" @click="handleSubmit"/>
<CloseOutlined :class="`${prefixCls}__icon `" @click="handleCancel"/>
</div>
</div>
</div>
</template>
<script lang="ts">
<script lang="tsx">
import type { CSSProperties, PropType } from 'vue';
import { computed, defineComponent, nextTick, ref, toRaw, unref, watchEffect } from 'vue';
import type { BasicColumn } from '../../types/table';
import type { EditRecordRow } from './index';
import { CheckOutlined, CloseOutlined, FormOutlined } from '@ant-design/icons-vue';
import { CellComponent } from './CellComponent';
import { useDesign } from '/@/hooks/web/useDesign';
import { useTableContext } from '../../hooks/useTableContext';
import clickOutside from '/@/directives/clickOutside';
import { propTypes } from '/@/utils/propTypes';
import { isArray, isBoolean, isFunction, isNumber, isString } from '/@/utils/is';
import { createPlaceholderMessage } from './helper';
import { omit, set } from 'lodash-es';
import { omit, pick, set } from 'lodash-es';
import { treeToList } from '/@/utils/helper/treeHelper';
import { Spin } from 'ant-design-vue';
export default defineComponent({
name: 'EditableCell',
components: { FormOutlined, CloseOutlined, CheckOutlined, CellComponent },
components: { FormOutlined, CloseOutlined, CheckOutlined, CellComponent, Spin },
directives: {
clickOutside,
},
@ -78,6 +47,7 @@ @@ -78,6 +47,7 @@
const optionsRef = ref<LabelValueOptions>([]);
const currentValueRef = ref<any>(props.value);
const defaultValueRef = ref<any>(props.value);
const spinning = ref<boolean>(false);
const { prefixCls } = useDesign('editable-cell');
@ -94,13 +64,6 @@ @@ -94,13 +64,6 @@
});
const getComponentProps = computed(() => {
const compProps = props.column?.editComponentProps ?? {};
const component = unref(getComponent);
const apiSelectProps: Recordable = {};
if (component === 'ApiSelect') {
apiSelectProps.cache = true;
}
const isCheckValue = unref(getIsCheckComp);
const valueField = isCheckValue ? 'checked' : 'value';
@ -108,18 +71,49 @@ @@ -108,18 +71,49 @@
const value = isCheckValue ? (isNumber(val) && isBoolean(val) ? val : !!val) : val;
let compProps = props.column?.editComponentProps ?? {};
const { record, column, index } = props;
if (isFunction(compProps)) {
compProps = compProps({ text: val, record, column, index }) ?? {};
}
const component = unref(getComponent);
const apiSelectProps: Recordable = {};
if (component === 'ApiSelect') {
apiSelectProps.cache = true;
}
upEditDynamicDisabled(record, column, value);
return {
size: 'small',
getPopupContainer: () => unref(table?.wrapRef.value) ?? document.body,
getCalendarContainer: () => unref(table?.wrapRef.value) ?? document.body,
placeholder: createPlaceholderMessage(unref(getComponent)),
...apiSelectProps,
...omit(compProps, 'onChange'),
...compProps,
[valueField]: value,
};
disabled: unref(getDisable),
} as any;
});
function upEditDynamicDisabled(record, column, value) {
if (!record) return false;
const { key, dataIndex } = column;
if (!key && !dataIndex) return;
const dataKey = (dataIndex || key) as string;
set(record, dataKey, value);
}
const getDisable = computed(() => {
const { editDynamicDisabled } = props.column;
let disabled = false;
if (isBoolean(editDynamicDisabled)) {
disabled = editDynamicDisabled;
}
if (isFunction(editDynamicDisabled)) {
const { record } = props;
disabled = editDynamicDisabled({ record });
}
return disabled;
});
const getValues = computed(() => {
const { editComponentProps, editValueMap } = props.column;
const { editValueMap } = props.column;
const value = unref(currentValueRef);
@ -132,7 +126,8 @@ @@ -132,7 +126,8 @@
return value;
}
const options: LabelValueOptions = editComponentProps?.options ?? (unref(optionsRef) || []);
const options: LabelValueOptions =
unref(getComponentProps)?.options ?? (unref(optionsRef) || []);
const option = options.find((item) => `${item.value}` === `${value}`);
return option?.label ?? value;
@ -183,14 +178,16 @@ @@ -183,14 +178,16 @@
const component = unref(getComponent);
if (!e) {
currentValueRef.value = e;
} else if (e?.target && Reflect.has(e.target, 'value')) {
currentValueRef.value = (e as ChangeEvent).target.value;
} else if (component === 'Checkbox') {
currentValueRef.value = (e as ChangeEvent).target.checked;
} else if (component === 'Switch') {
currentValueRef.value = e;
} else if (e?.target && Reflect.has(e.target, 'value')) {
currentValueRef.value = (e as ChangeEvent).target.value;
} else if (isString(e) || isBoolean(e) || isNumber(e) || isArray(e)) {
currentValueRef.value = e;
}
const onChange = props.column?.editComponentProps?.onChange;
const onChange = unref(getComponentProps)?.onChange;
if (onChange && isFunction(onChange)) onChange(...arguments);
table.emit?.('edit-change', {
@ -243,9 +240,38 @@ @@ -243,9 +240,38 @@
const dataKey = (dataIndex || key) as string;
if (!record.editable) {
const { getBindValues } = table;
const { beforeEditSubmit, columns } = unref(getBindValues);
if (beforeEditSubmit && isFunction(beforeEditSubmit)) {
spinning.value = true;
const keys: string[] = columns
.map((_column) => _column.dataIndex)
.filter((field) => !!field) as string[];
let result: any = true;
try {
result = await beforeEditSubmit({
record: pick(record, keys),
index,
key: dataKey as string,
value,
});
} catch (e) {
result = false;
} finally {
spinning.value = false;
}
if (result === false) {
return;
}
}
}
set(record, dataKey, value);
//const record = await table.updateTableData(index, dataKey, value);
needEmit && table.emit?.('edit-end', { record, index, key, value });
needEmit && table.emit?.('edit-end', { record, index, key: dataKey, value });
isEdit.value = false;
}
@ -256,6 +282,10 @@ @@ -256,6 +282,10 @@
handleSubmit();
}
function handleSubmitClick() {
handleSubmit();
}
function handleCancel() {
isEdit.value = false;
currentValueRef.value = defaultValueRef.value;
@ -282,7 +312,7 @@ @@ -282,7 +312,7 @@
// only ApiSelect or TreeSelect
function handleOptionsChange(options: LabelValueOptions) {
const { replaceFields } = props.column?.editComponentProps ?? {};
const { replaceFields } = unref(getComponentProps);
const component = unref(getComponent);
if (component === 'ApiTreeSelect') {
const { title = 'title', value = 'value', children = 'children' } = replaceFields || {};
@ -315,7 +345,7 @@ @@ -315,7 +345,7 @@
if (props.column.dataIndex) {
if (!props.record.editValueRefs) props.record.editValueRefs = {};
props.record.editValueRefs[props.column.dataIndex] = currentValueRef;
props.record.editValueRefs[props.column.dataIndex as any] = currentValueRef;
}
/* eslint-disable */
props.record.onCancelEdit = () => {
@ -354,9 +384,63 @@ @@ -354,9 +384,63 @@
getRowEditable,
getValues,
handleEnter,
// getSize,
handleSubmitClick,
spinning,
};
},
render() {
return (
<div class={this.prefixCls}>
<div
v-show={!this.isEdit}
class={{ [`${this.prefixCls}__normal`]: true, 'ellipsis-cell': this.column.ellipsis }}
onClick={this.handleEdit}
>
<div class="cell-content" title={this.column.ellipsis ? this.getValues ?? '' : ''}>
{this.column.editRender
? this.column.editRender({
text: this.value,
record: this.record as Recordable,
column: this.column,
index: this.index,
})
: this.getValues
? this.getValues
: '\u00A0'}
</div>
{!this.column.editRow && <FormOutlined class={`${this.prefixCls}__normal-icon`} />}
</div>
{this.isEdit && (
<Spin spinning={this.spinning}>
<div class={`${this.prefixCls}__wrapper`} v-click-outside={this.onClickOutside}>
<CellComponent
{...this.getComponentProps}
component={this.getComponent}
style={this.getWrapperStyle}
popoverVisible={this.getRuleVisible}
rule={this.getRule}
ruleMessage={this.ruleMessage}
class={this.getWrapperClass}
ref="elRef"
onChange={this.handleChange}
onOptionsChange={this.handleOptionsChange}
onPressEnter={this.handleEnter}
/>
{!this.getRowEditable && (
<div class={`${this.prefixCls}__action`}>
<CheckOutlined
class={[`${this.prefixCls}__icon`, 'mx-2']}
onClick={this.handleSubmitClick}
/>
<CloseOutlined class={`${this.prefixCls}__icon `} onClick={this.handleCancel} />
</div>
)}
</div>
</Spin>
)}
</div>
);
},
});
</script>
<style lang="less">

30
src/components/Table/src/types/table.ts

@ -362,6 +362,18 @@ export interface BasicTableProps<T = any> { @@ -362,6 +362,18 @@ export interface BasicTableProps<T = any> {
*/
transformCellText?: Function;
/**
* Callback executed before editable cell submit value, not for row-editor
*
* The cell will not submit data while callback return false
*/
beforeEditSubmit?: (data: {
record: Recordable;
index: number;
key: string | number;
value: any;
}) => Promise<any>;
/**
* Callback executed when pagination, filters or sorter is changed
* @param pagination
@ -423,7 +435,14 @@ export interface BasicColumn extends ColumnProps { @@ -423,7 +435,14 @@ export interface BasicColumn extends ColumnProps {
editRow?: boolean;
editable?: boolean;
editComponent?: ComponentType;
editComponentProps?: Recordable;
editComponentProps?:
| ((opt: {
text: string | number | boolean | Recordable;
record: Recordable;
column: BasicColumn;
index: number;
}) => Recordable)
| Recordable;
editRule?: boolean | ((text: string, record: Recordable) => Promise<string>);
editValueMap?: (value: any) => string;
onEditRow?: () => void;
@ -431,6 +450,15 @@ export interface BasicColumn extends ColumnProps { @@ -431,6 +450,15 @@ export interface BasicColumn extends ColumnProps {
auth?: string | string[];
// 业务控制是否显示
ifShow?: boolean | ((column: BasicColumn) => boolean);
// 自定义修改后显示的内容
editRender?: (opt: {
text: string | number | boolean | Recordable;
record: Recordable;
column: BasicColumn;
index: number;
}) => VNodeChild | JSX.Element;
// 动态 Disabled
editDynamicDisabled?: boolean | ((record: Recordable) => boolean);
}
export type ColumnChangeParam = {

Loading…
Cancel
Save