Skip to content

Commit

Permalink
fix: restore lost changes
Browse files Browse the repository at this point in the history
  • Loading branch information
colinin committed Apr 18, 2023
1 parent 61f468e commit 6e468b8
Show file tree
Hide file tree
Showing 28 changed files with 359 additions and 205 deletions.
73 changes: 70 additions & 3 deletions apps/vue/src/components/Excel/src/Export2Excel.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import * as xlsx from 'xlsx';
import type { WorkBook } from 'xlsx';
import type { JsonToSheet, AoAToSheet } from './typing';
import { AoaToMultipleSheet, JsonToMultipleSheet } from './typing';

const { utils, writeFile } = xlsx;

const DEF_FILE_NAME = 'excel-list.xlsx';
const DEF_SHEET_NAME = 'sheet';

/**
* @param data source data
* @param worksheet worksheet object
* @param min min width
*/
function setColumnWidth(data, worksheet, min = 3) {
function setColumnWidth(data, worksheet, min = 3) {
const obj = {};
worksheet['!cols'] = [];
data.forEach((item) => {
Expand All @@ -32,6 +34,7 @@ export function jsonToSheetXlsx<T = any>({
data,
header,
filename = DEF_FILE_NAME,
sheetName = DEF_SHEET_NAME,
json2sheetOpts = {},
write2excelOpts = { bookType: 'xlsx' },
}: JsonToSheet<T>) {
Expand All @@ -45,9 +48,9 @@ export function jsonToSheetXlsx<T = any>({
setColumnWidth(arrData, worksheet);
/* add worksheet to workbook */
const workbook: WorkBook = {
SheetNames: [filename],
SheetNames: [sheetName],
Sheets: {
[filename]: worksheet,
[sheetName]: worksheet,
},
};
/* output format determined by filename */
Expand Down Expand Up @@ -79,3 +82,67 @@ export function aoaToSheetXlsx<T = any>({
writeFile(workbook, filename, write2excelOpts);
/* at this point, out.xlsb will have been downloaded */
}

/**
* json导出多Sheet的Xlsx
* @param sheetList 多sheet配置
* @param filename 文件名(包含后缀)
* @param write2excelOpts 文件配置
*/
export function jsonToMultipleSheetXlsx<T = any>({
sheetList,
filename = DEF_FILE_NAME,
write2excelOpts = { bookType: 'xlsx' },
}: JsonToMultipleSheet<T>) {
const workbook: WorkBook = {
SheetNames: [],
Sheets: {},
};
sheetList.forEach((p, index) => {
const arrData = [...p.data];
if (p.header) {
arrData.unshift(p.header);
p.json2sheetOpts = p.json2sheetOpts || {};
p.json2sheetOpts.skipHeader = true;
}

const worksheet = utils.json_to_sheet(arrData, p.json2sheetOpts);
setColumnWidth(arrData, worksheet);

p.sheetName = p.sheetName || `${DEF_SHEET_NAME}${index}`;
workbook.SheetNames.push(p.sheetName);
workbook.Sheets[p.sheetName] = worksheet;
});
writeFile(workbook, filename, write2excelOpts);
}

/**
* aoa导出多Sheet的Xlsx
* @param sheetList 多sheet配置
* @param filename 文件名(包含后缀)
* @param write2excelOpts 文件配置
*/
export function aoaToMultipleSheetXlsx<T = any>({
sheetList,
filename = DEF_FILE_NAME,
write2excelOpts = { bookType: 'xlsx' },
}: AoaToMultipleSheet<T>) {
const workbook: WorkBook = {
SheetNames: [],
Sheets: {},
};
sheetList.forEach((p, index) => {
const arrData = [...p.data];
if (p.header) {
arrData.unshift(p.header);
}
const worksheet = utils.aoa_to_sheet(arrData);

p.sheetName = p.sheetName || `${DEF_SHEET_NAME}${index}`;
workbook.SheetNames.push(p.sheetName);
workbook.Sheets[p.sheetName] = worksheet;
});
/* output format determined by filename */
writeFile(workbook, filename, write2excelOpts);
/* at this point, out.xlsb will have been downloaded */
}
14 changes: 14 additions & 0 deletions apps/vue/src/components/Excel/src/typing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface JsonToSheet<T = any> {
data: T[];
header?: T;
filename?: string;
sheetName?: string;
json2sheetOpts?: JSON2SheetOpts;
write2excelOpts?: WritingOptions;
}
Expand All @@ -18,10 +19,23 @@ export interface AoAToSheet<T = any> {
data: T[][];
header?: T[];
filename?: string;
sheetName?: string;
write2excelOpts?: WritingOptions;
}

export interface ExportModalResult {
filename: string;
bookType: BookType;
}

export interface JsonToMultipleSheet<T = any> {
sheetList: JsonToSheet<T>[];
filename?: string;
write2excelOpts?: WritingOptions;
}

export interface AoaToMultipleSheet<T = any> {
sheetList: AoAToSheet<T>[];
filename?: string;
write2excelOpts?: WritingOptions;
}
4 changes: 2 additions & 2 deletions apps/vue/src/components/Form/src/components/ApiSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@
return unref(options).reduce((prev, next: Recordable) => {
if (next) {
const value = next[valueField];
const value = get(next, valueField);
prev.push({
...omit(next, [labelField, valueField]),
label: next[labelField],
label: get(next, labelField),
value: numberToString ? `${value}` : value,
});
}
Expand Down
3 changes: 3 additions & 0 deletions apps/vue/src/components/Form/src/components/ApiTransfer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
if (Array.isArray(props.value)) {
return props.value;
}
if (Array.isArray(props.targetKeys)){
return props.targetKeys;
}
return [];
});
function handleChange(keys: string[], direction: TransferDirection, moveKeys: string[]) {
Expand Down
88 changes: 71 additions & 17 deletions apps/vue/src/components/Form/src/hooks/useFormEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { deepMerge } from '/@/utils';
import { dateItemType, handleInputNumberValue, defaultValueComponents } from '../helper';
import { dateUtil } from '/@/utils/dateUtil';
import { cloneDeep, uniqBy } from 'lodash-es';
import { cloneDeep, set, uniqBy } from 'lodash-es';
import { error } from '/@/utils/log';

interface UseFormActionContext {
Expand All @@ -27,6 +27,47 @@ interface UseFormActionContext {
schemaRef: Ref<FormSchema[]>;
handleFormValues: Fn;
}

function tryConstructArray(field: string, values: Recordable = {}): any[] | undefined {
const pattern = /^\[(.+)\]$/;
if (pattern.test(field)) {
const match = field.match(pattern);
if (match && match[1]) {
const keys = match[1].split(',');
if (!keys.length) {
return undefined;
}

const result = [];
keys.forEach((k, index) => {
set(result, index, values[k.trim()]);
});

return result.length ? result : undefined;
}
}
}

function tryConstructObject(field: string, values: Recordable = {}): Recordable | undefined {
const pattern = /^\{(.+)\}$/;
if (pattern.test(field)) {
const match = field.match(pattern);
if (match && match[1]) {
const keys = match[1].split(',');
if (!keys.length) {
return;
}

const result = {};
keys.forEach((k) => {
set(result, k.trim(), values[k.trim()]);
});

return Object.values(result).filter(Boolean).length ? result : undefined;
}
}
}

export function useFormEvents({
emit,
getProps,
Expand Down Expand Up @@ -67,51 +108,61 @@ export function useFormEvents({

// key 支持 a.b.c 的嵌套写法
const delimiter = '.';
const nestKeyArray = fields.filter((item) => item.indexOf(delimiter) >= 0);
const nestKeyArray = fields.filter((item) => String(item).indexOf(delimiter) >= 0);

const validKeys: string[] = [];
Object.keys(values).forEach((key) => {
fields.forEach((key) => {
const schema = unref(getSchema).find((item) => item.field === key);
let value = values[key];

const hasKey = Reflect.has(values, key);

value = handleInputNumberValue(schema?.component, value);
const { componentProps } = schema || {};
let _props = componentProps as any;
if (typeof componentProps === 'function') {
_props = _props({ formModel: unref(formModel) });
}

const constructValue = tryConstructArray(key, values) || tryConstructObject(key, values);

// 0| '' is allow
if (hasKey && fields.includes(key)) {
if (hasKey || !!constructValue) {
const fieldValue = constructValue || value;
// time type
if (itemIsDateType(key)) {
if (Array.isArray(value)) {
if (Array.isArray(fieldValue)) {
const arr: any[] = [];
for (const ele of value) {
for (const ele of fieldValue) {
arr.push(ele ? dateUtil(ele) : null);
}
formModel[key] = arr;
unref(formModel)[key] = arr;
} else {
const { componentProps } = schema || {};
let _props = componentProps as any;
if (typeof componentProps === 'function') {
_props = _props({ formModel });
}
formModel[key] = value ? (_props?.valueFormat ? value : dateUtil(value)) : null;
unref(formModel)[key] = fieldValue
? _props?.valueFormat
? fieldValue
: dateUtil(fieldValue)
: null;
}
} else {
formModel[key] = value;
unref(formModel)[key] = fieldValue;
}
// if (_props?.onChange) {
// _props?.onChange(fieldValue);
// }
validKeys.push(key);
} else {
nestKeyArray.forEach((nestKey: string) => {
try {
const value = nestKey.split('.').reduce((out, item) => out[item], values);
if (isDef(value)) {
formModel[nestKey] = value;
unref(formModel)[nestKey] = unref(value);
validKeys.push(nestKey);
}
} catch (e) {
// key not exist
if (isDef(defaultValueRef.value[nestKey])) {
//formModel[nestKey] = defaultValueRef.value[nestKey];
formModel[nestKey] = cloneDeep(defaultValueRef.value[nestKey]);
unref(formModel)[nestKey] = cloneDeep(unref(defaultValueRef.value[nestKey]));
}
}
});
Expand Down Expand Up @@ -313,6 +364,9 @@ export function useFormEvents({
const res = handleFormValues(values);
emit('submit', res);
} catch (error: any) {
if (error?.outOfDate === false && error?.errorFields) {
return;
}
throw new Error(error);
}
}
Expand Down
2 changes: 1 addition & 1 deletion apps/vue/src/components/Form/src/types/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface ButtonProps extends AntdButtonProps {

export interface FormActionType {
submit: () => Promise<void>;
setFieldsValue: <T>(values: T) => Promise<void>;
setFieldsValue: (values: Recordable) => Promise<void>;
resetFields: () => Promise<void>;
getFieldsValue: () => Recordable;
clearValidate: (name?: string | string[]) => Promise<void>;
Expand Down

0 comments on commit 6e468b8

Please sign in to comment.