修改错误

new-map
ihzero 2022-10-27 10:33:48 +08:00
parent 3a56901da2
commit 3fbe2b253c
7 changed files with 361 additions and 16 deletions

View File

@ -0,0 +1,6 @@
import { withInstall } from '/@/utils';
import description from './src/Description.vue';
export * from './src/typing';
export { useDescription } from './src/useDescription';
export const Description = withInstall(description);

View File

@ -0,0 +1,184 @@
<script lang="tsx">
import type { DescriptionProps, DescInstance, DescItem } from './typing';
import type { DescriptionsProps } from 'ant-design-vue/es/descriptions/index';
import type { CSSProperties } from 'vue';
import type { CollapseContainerOptions } from '/@/components/Container/index';
import { defineComponent, computed, ref, unref, toRefs } from 'vue';
import { get } from 'lodash-es';
import { Descriptions } from 'ant-design-vue';
import { CollapseContainer } from '/@/components/Container/index';
import { useDesign } from '/@/hooks/web/useDesign';
import { isFunction } from '/@/utils/is';
import { getSlot } from '/@/utils/helper/tsxHelper';
import { useAttrs } from '/@/hooks/core/useAttrs';
const props = {
useCollapse: { type: Boolean, default: true },
title: { type: String, default: '' },
size: {
type: String,
validator: (v) => ['small', 'default', 'middle', undefined].includes(v),
default: 'small',
},
bordered: { type: Boolean, default: true },
column: {
type: [Number, Object] as PropType<number | Recordable>,
default: () => {
return { xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 };
},
},
collapseOptions: {
type: Object as PropType<CollapseContainerOptions>,
default: null,
},
schema: {
type: Array as PropType<DescItem[]>,
default: () => [],
},
data: { type: Object },
};
export default defineComponent({
name: 'Description',
props,
emits: ['register'],
setup(props, { slots, emit }) {
const propsRef = ref<Partial<DescriptionProps> | null>(null);
const { prefixCls } = useDesign('description');
const attrs = useAttrs();
// Custom title component: get title
const getMergeProps = computed(() => {
return {
...props,
...(unref(propsRef) as Recordable),
} as DescriptionProps;
});
const getProps = computed(() => {
const opt = {
...unref(getMergeProps),
title: undefined,
};
return opt as DescriptionProps;
});
/**
* @description: Whether to setting title
*/
const useWrapper = computed(() => !!unref(getMergeProps).title);
/**
* @description: Get configuration Collapse
*/
const getCollapseOptions = computed((): CollapseContainerOptions => {
return {
// Cannot be expanded by default
canExpand: false,
...unref(getProps).collapseOptions,
};
});
const getDescriptionsProps = computed(() => {
return { ...unref(attrs), ...unref(getProps) } as DescriptionsProps;
});
/**
* @description:设置desc
*/
function setDescProps(descProps: Partial<DescriptionProps>): void {
// Keep the last setDrawerProps
propsRef.value = { ...(unref(propsRef) as Recordable), ...descProps } as Recordable;
}
// Prevent line breaks
function renderLabel({ label, labelMinWidth, labelStyle }: DescItem) {
if (!labelStyle && !labelMinWidth) {
return label;
}
const labelStyles: CSSProperties = {
...labelStyle,
minWidth: `${labelMinWidth}px `,
};
return <div style={labelStyles}>{label}</div>;
}
function renderItem() {
const { schema, data } = unref(getProps);
return unref(schema)
.map((item) => {
const { render, field, span, show, contentMinWidth } = item;
if (show && isFunction(show) && !show(data)) {
return null;
}
const getContent = () => {
const _data = unref(getProps)?.data;
if (!_data) {
return null;
}
const getField = get(_data, field);
if (getField && !toRefs(_data).hasOwnProperty(field)) {
return isFunction(render) ? render('', _data) : '';
}
return isFunction(render) ? render(getField, _data) : getField ?? '';
};
const width = contentMinWidth;
return (
<Descriptions.Item label={renderLabel(item)} key={field} span={span}>
{() => {
if (!contentMinWidth) {
return getContent();
}
const style: CSSProperties = {
minWidth: `${width}px`,
};
return <div style={style}>{getContent()}</div>;
}}
</Descriptions.Item>
);
})
.filter((item) => !!item);
}
const renderDesc = () => {
return (
<Descriptions class={`${prefixCls}`} {...(unref(getDescriptionsProps) as any)}>
{renderItem()}
</Descriptions>
);
};
const renderContainer = () => {
const content = props.useCollapse ? renderDesc() : <div>{renderDesc()}</div>;
// Reduce the dom level
if (!props.useCollapse) {
return content;
}
const { canExpand, helpMessage } = unref(getCollapseOptions);
const { title } = unref(getMergeProps);
return (
<CollapseContainer title={title} canExpan={canExpand} helpMessage={helpMessage}>
{{
default: () => content,
action: () => getSlot(slots, 'action'),
}}
</CollapseContainer>
);
};
const methods: DescInstance = {
setDescProps,
};
emit('register', methods);
return () => (unref(useWrapper) ? renderContainer() : renderDesc());
},
});
</script>

View File

@ -0,0 +1,50 @@
import type { VNode, CSSProperties } from 'vue';
import type { CollapseContainerOptions } from '/@/components/Container/index';
import type { DescriptionsProps } from 'ant-design-vue/es/descriptions/index';
export interface DescItem {
labelMinWidth?: number;
contentMinWidth?: number;
labelStyle?: CSSProperties;
field: string;
label: string | VNode | JSX.Element;
// Merge column
span?: number;
show?: (...arg: any) => boolean;
// render
render?: (
val: any,
data: Recordable,
) => VNode | undefined | JSX.Element | Element | string | number;
}
export interface DescriptionProps extends DescriptionsProps {
// Whether to include the collapse component
useCollapse?: boolean;
/**
* item configuration
* @type DescItem
*/
schema: DescItem[];
/**
*
* @type object
*/
data: Recordable;
/**
* Built-in CollapseContainer component configuration
* @type CollapseContainerOptions
*/
collapseOptions?: CollapseContainerOptions;
}
export interface DescInstance {
setDescProps(descProps: Partial<DescriptionProps>): void;
}
export type Register = (descInstance: DescInstance) => void;
/**
* @description:
*/
export type UseDescReturnType = [Register, DescInstance];

View File

@ -0,0 +1,28 @@
import type { DescriptionProps, DescInstance, UseDescReturnType } from './typing';
import { ref, getCurrentInstance, unref } from 'vue';
import { isProdMode } from '/@/utils/env';
export function useDescription(props?: Partial<DescriptionProps>): UseDescReturnType {
if (!getCurrentInstance()) {
throw new Error('useDescription() can only be used inside setup() or functional components!');
}
const desc = ref<Nullable<DescInstance>>(null);
const loaded = ref(false);
function register(instance: DescInstance) {
if (unref(loaded) && isProdMode()) {
return;
}
desc.value = instance;
props && instance.setDescProps(props);
loaded.value = true;
}
const methods: DescInstance = {
setDescProps: (descProps: Partial<DescriptionProps>): void => {
unref(desc)?.setDescProps(descProps);
},
};
return [register, methods];
}

View File

@ -0,0 +1,77 @@
import type { ErrorLogInfo } from '/#/store';
import { defineStore } from 'pinia';
import { store } from '/@/store';
import { formatToDateTime } from '/@/utils/dateUtil';
import projectSetting from '/@/settings/projectSetting';
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
export interface ErrorLogState {
errorLogInfoList: Nullable<ErrorLogInfo[]>;
errorLogListCount: number;
}
export const useErrorLogStore = defineStore({
id: 'app-error-log',
state: (): ErrorLogState => ({
errorLogInfoList: null,
errorLogListCount: 0,
}),
getters: {
getErrorLogInfoList(): ErrorLogInfo[] {
return this.errorLogInfoList || [];
},
getErrorLogListCount(): number {
return this.errorLogListCount;
},
},
actions: {
addErrorLogInfo(info: ErrorLogInfo) {
const item = {
...info,
time: formatToDateTime(new Date()),
};
this.errorLogInfoList = [item, ...(this.errorLogInfoList || [])];
this.errorLogListCount += 1;
},
setErrorLogListCount(count: number): void {
this.errorLogListCount = count;
},
/**
* Triggered after ajax request error
* @param error
* @returns
*/
addAjaxErrorInfo(error) {
const { useErrorHandle } = projectSetting;
if (!useErrorHandle) {
return;
}
const errInfo: Partial<ErrorLogInfo> = {
message: error.message,
type: ErrorTypeEnum.AJAX,
};
if (error.response) {
const {
config: { url = '', data: params = '', method = 'get', headers = {} } = {},
data = {},
} = error.response;
errInfo.url = url;
errInfo.name = 'Ajax Error!';
errInfo.file = '-';
errInfo.stack = JSON.stringify(data);
errInfo.detail = JSON.stringify({ params, method, headers });
}
this.addErrorLogInfo(errInfo as ErrorLogInfo);
},
},
});
// Need to be used outside the setup
export function useErrorLogStoreWithOut() {
return useErrorLogStore(store);
}

View File

@ -13,7 +13,7 @@
<div class="flex">
<div class="w-250px">
<div class="flex">
<img class="w-40px h-40px" src="src/assets/images/up-icon.png" alt="" srcset="" />
<img class="w-40px h-40px" src="/@/assets/images/up-icon.png" alt="" srcset="" />
<div class="ml-20px">
<div class="text-[#828fa2]">历史最高价格</div>
<div>
@ -23,7 +23,7 @@
</div>
</div>
<div class="flex mt-40px">
<img class="w-40px h-40px" src="src/assets/images/down-icon.png" alt="" srcset="" />
<img class="w-40px h-40px" src="/@/assets/images/down-icon.png" alt="" srcset="" />
<div class="ml-20px">
<div class="text-[#828fa2]">历史最低价格</div>
<div>
@ -41,9 +41,9 @@
</template>
<script lang="ts">
import { defineComponent, ref, Ref, watch } from 'vue';
import { Card, Radio, DatePicker } from 'ant-design-vue';
import { useECharts } from '/@/hooks/web/useECharts';
import { defineComponent, ref, Ref, watch } from 'vue'
import { Card, Radio, DatePicker } from 'ant-design-vue'
import { useECharts } from '/@/hooks/web/useECharts'
const dayGroup = [
{
title: '今天',
@ -61,7 +61,7 @@
title: '近一年',
value: 'd',
},
];
]
export default defineComponent({
components: {
[Card.name]: Card,
@ -82,14 +82,14 @@
},
setup(props) {
const value = ref<String>('a');
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
const value = ref<String>('a')
const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
watch(
() => props.loading,
() => {
if (props.loading) {
return;
return
}
setOptions({
@ -138,20 +138,20 @@
},
},
],
});
})
},
{
immediate: true,
},
);
)
return {
value,
dayGroup,
chartRef,
};
}
},
});
})
</script>
<style lang="scss" scoped></style>

View File

@ -41,7 +41,7 @@
import { useMessage } from '/@/hooks/web/useMessage'
import { useI18n } from '/@/hooks/web/useI18n'
import { useErrorLogStore } from '/@/store/modules/errorLog'
import { fireErrorApi } from '/@/api/demo/error'
// import { fireErrorApi } from '/@/api/demo/error'
import { getColumns } from './data'
import { cloneDeep } from 'lodash-es'
@ -92,6 +92,6 @@
}
async function fireAjaxError() {
await fireErrorApi()
// await fireErrorApi()
}
</script>