diff --git a/packages/opendesign/src/components/index.scss b/packages/opendesign/src/components/index.scss
index a9c77e309aefe541ac20a6583d38661aa193f217..75a57b337686e8966c41a32bd1439945a993b9ed 100644
--- a/packages/opendesign/src/components/index.scss
+++ b/packages/opendesign/src/components/index.scss
@@ -33,3 +33,4 @@
@use './message/style/index.scss' as *;
@use './cascader/style/index.scss' as *;
@use './grid/style/index.scss' as *;
+@use './result/style/index.scss' as *;
diff --git a/packages/opendesign/src/components/index.ts b/packages/opendesign/src/components/index.ts
index c1e067ebf72e810d59588601ab21fdf4c35572b9..344a2dd78c39d5224bee867768d9692edc204e75 100644
--- a/packages/opendesign/src/components/index.ts
+++ b/packages/opendesign/src/components/index.ts
@@ -36,6 +36,7 @@ export * from './message';
export * from './slides';
export * from './cascader';
export * from './grid';
+export * from './result';
// export * from './scrollbar';
export * from './intersection-observer';
diff --git a/packages/opendesign/src/components/result/OResult.vue b/packages/opendesign/src/components/result/OResult.vue
new file mode 100644
index 0000000000000000000000000000000000000000..40daeefa8411ef31a500c228502782728f30bfb9
--- /dev/null
+++ b/packages/opendesign/src/components/result/OResult.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ props.title }}
+
+
+
+
+ {{ props.description }}
+
+
+
+
+
+
+
+
diff --git a/packages/opendesign/src/components/result/__demo__/IndexResult.vue b/packages/opendesign/src/components/result/__demo__/IndexResult.vue
new file mode 100644
index 0000000000000000000000000000000000000000..4fc9388115c0e05b1710308b6635f3f8b7ef396f
--- /dev/null
+++ b/packages/opendesign/src/components/result/__demo__/IndexResult.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
diff --git a/packages/opendesign/src/components/result/__demo__/ResultBasic.vue b/packages/opendesign/src/components/result/__demo__/ResultBasic.vue
new file mode 100644
index 0000000000000000000000000000000000000000..41ef166f6bb9552977f2f75f75840f01399df390
--- /dev/null
+++ b/packages/opendesign/src/components/result/__demo__/ResultBasic.vue
@@ -0,0 +1,16 @@
+
+
+
+ 基础用法
+
+
diff --git a/packages/opendesign/src/components/result/__demo__/ResultSlots.vue b/packages/opendesign/src/components/result/__demo__/ResultSlots.vue
new file mode 100644
index 0000000000000000000000000000000000000000..c2a8ca019e3d5ae4ee2913eab919a17f1b02b44e
--- /dev/null
+++ b/packages/opendesign/src/components/result/__demo__/ResultSlots.vue
@@ -0,0 +1,30 @@
+
+
+
+ 插槽
+
+
+
+
+
+ 404
+ 页面走丢了
+
+ 返回
+
+
+
+
+
+
diff --git a/packages/opendesign/src/components/result/index.ts b/packages/opendesign/src/components/result/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1af6c728e81cb7f8f0c7dbed74209369383cae70
--- /dev/null
+++ b/packages/opendesign/src/components/result/index.ts
@@ -0,0 +1,13 @@
+import type { App } from 'vue';
+
+import _OResult from './OResult.vue';
+
+const OResult = Object.assign(_OResult, {
+ install(app: App) {
+ app.component(_OResult.name, _OResult);
+ },
+});
+
+export * from './types';
+
+export { OResult };
diff --git a/packages/opendesign/src/components/result/style/index.scss b/packages/opendesign/src/components/result/style/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..bf37a5ee925637b68be983288d1769d7711e80b5
--- /dev/null
+++ b/packages/opendesign/src/components/result/style/index.scss
@@ -0,0 +1,48 @@
+@use './var.scss';
+
+.o-result {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ padding: var(--result-padding);
+}
+
+.o-result-icon {
+ width: var(--result-icon-size);
+ height: var(--result-icon-size);
+ font-size: var(--result-icon-size);
+ color: var(--result-icon-color);
+}
+
+.o-result-title {
+ color: var(--result-title-color);
+ font-size: var(--result-title-text-size);
+ line-height: var(--result-title-text-height);
+ font-weight: 600;
+ margin-top: var(--result-title-margin-top);
+
+ p {
+ margin: 0;
+ }
+}
+
+.o-result-description {
+ color: var(--result-desc-color);
+ font-size: var(--result-desc-text-size);
+ line-height: var(--result-desc-text-height);
+ margin-top: var(--result-desc-margin-top);
+ p {
+ margin: 0;
+ }
+}
+
+.o-result-extra {
+ margin-top: var(--result-extra-margin-top);
+}
+
+.o-result-icon-custom {
+ width: auto;
+ height: auto;
+}
diff --git a/packages/opendesign/src/components/result/style/index.ts b/packages/opendesign/src/components/result/style/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..591b2fbd72dcd5e987362d645b561bd2fac42716
--- /dev/null
+++ b/packages/opendesign/src/components/result/style/index.ts
@@ -0,0 +1,2 @@
+import '../../style';
+import './index.scss';
diff --git a/packages/opendesign/src/components/result/style/var.scss b/packages/opendesign/src/components/result/style/var.scss
new file mode 100644
index 0000000000000000000000000000000000000000..de5267de7e57b57ca59156b8e90e01f3a0d9582f
--- /dev/null
+++ b/packages/opendesign/src/components/result/style/var.scss
@@ -0,0 +1,30 @@
+.o-result {
+ --result-padding: 40px;
+
+ --result-icon-size: 60px;
+ --result-icon-color: var(--o-color-primary1);
+
+ --result-title-color: var(--o-color-info1);
+ --result-title-text-size: var(--o-font_size-h3);
+ --result-title-text-height: var(--o-line_height-h3);
+ --result-title-margin-top: 16px;
+
+ --result-desc-color: var(--o-color-info2);
+ --result-desc-text-size: var(--o-font_size-text1);
+ --result-desc-text-height: var(--o-line_height-text1);
+ --result-desc-margin-top: 8px;
+
+ --result-extra-margin-top: 24px;
+}
+
+.o-result-success {
+ --result-icon-color: var(--o-color-success1);
+}
+
+.o-result-warning {
+ --result-icon-color: var(--o-color-warning1);
+}
+
+.o-result-danger {
+ --result-icon-color: var(--o-color-danger1);
+}
diff --git a/packages/opendesign/src/components/result/types.ts b/packages/opendesign/src/components/result/types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f40d843aeda0dfae06ce2ca84f68e817a67cb0ef
--- /dev/null
+++ b/packages/opendesign/src/components/result/types.ts
@@ -0,0 +1,28 @@
+import { ExtractPropTypes, PropType } from 'vue';
+
+export const ResultStatusTypes = ['info', 'success', 'warning', 'danger'] as const;
+export type ResultStatusT = typeof ResultStatusTypes[number];
+
+export const resultProps = {
+ /**
+ * 状态
+ */
+ status: {
+ type: String as PropType,
+ default: 'info',
+ },
+ /**
+ * 标题
+ */
+ title: {
+ type: String,
+ },
+ /**
+ * 描述
+ **/
+ description: {
+ type: String,
+ },
+};
+
+export type ResultPropsT = ExtractPropTypes;
diff --git a/packages/portal/src/router.ts b/packages/portal/src/router.ts
index cf16f3054ecc8d4b627eaf0feddd12541a8b0b62..dd83d92d32b7d418c35591de101cc2fb90869399 100644
--- a/packages/portal/src/router.ts
+++ b/packages/portal/src/router.ts
@@ -194,6 +194,12 @@ export const routes = [
label: '加载 Loading',
component: () => import('@components/loading/__demo__/IndexLoading.vue'),
},
+ {
+ path: '/result',
+ name: 'Result',
+ label: '结果 Result',
+ component: () => import('@components/result/__demo__/IndexResult.vue'),
+ },
{
path: '/resize-observer',
name: 'ResizeObserver',