create-weapp-vite 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/{chunk-CP2T5O3U.js → chunk-KDUDSVZ5.js} +2 -2
  2. package/dist/cli.cjs +2 -2
  3. package/dist/cli.js +1 -1
  4. package/dist/index.cjs +2 -2
  5. package/dist/index.js +1 -1
  6. package/package.json +1 -1
  7. package/templates/wevu-tdesign/README.md +5 -0
  8. package/templates/wevu-tdesign/components.d.ts +1 -1
  9. package/templates/wevu-tdesign/public/tabbar/ability-active.png +0 -0
  10. package/templates/wevu-tdesign/public/tabbar/ability.png +0 -0
  11. package/templates/wevu-tdesign/public/tabbar/data-active.png +0 -0
  12. package/templates/wevu-tdesign/public/tabbar/data.png +0 -0
  13. package/templates/wevu-tdesign/public/tabbar/form-active.png +0 -0
  14. package/templates/wevu-tdesign/public/tabbar/form.png +0 -0
  15. package/templates/wevu-tdesign/public/tabbar/home-active.png +0 -0
  16. package/templates/wevu-tdesign/public/tabbar/home.png +0 -0
  17. package/templates/wevu-tdesign/public/tabbar/list-active.png +0 -0
  18. package/templates/wevu-tdesign/public/tabbar/list.png +0 -0
  19. package/templates/wevu-tdesign/src/app.vue +60 -2
  20. package/templates/wevu-tdesign/src/components/EmptyState/index.vue +36 -0
  21. package/templates/wevu-tdesign/src/components/FilterBar/index.vue +63 -0
  22. package/templates/wevu-tdesign/src/components/FormRow/index.vue +43 -0
  23. package/templates/wevu-tdesign/src/components/FormStep/index.vue +48 -0
  24. package/templates/wevu-tdesign/src/components/KpiBoard/index.vue +146 -0
  25. package/templates/wevu-tdesign/src/components/QuickActionGrid/index.vue +90 -0
  26. package/templates/wevu-tdesign/src/components/ResultCard/index.vue +51 -0
  27. package/templates/wevu-tdesign/src/components/SectionTitle/index.vue +34 -0
  28. package/templates/wevu-tdesign/src/components/TrendCard/index.vue +101 -0
  29. package/templates/wevu-tdesign/src/pages/ability/index.vue +177 -0
  30. package/templates/wevu-tdesign/src/pages/data/index.vue +188 -0
  31. package/templates/wevu-tdesign/src/pages/form/index.vue +249 -0
  32. package/templates/wevu-tdesign/src/pages/index/index.vue +228 -126
  33. package/templates/wevu-tdesign/src/pages/list/index.vue +178 -0
  34. package/templates/wevu-tdesign/src/subpackages/ability/index.vue +106 -0
  35. package/templates/wevu-tdesign/src/subpackages/lab/index.vue +136 -0
  36. package/templates/wevu-tdesign/src/vite-env.d.ts +4 -0
  37. package/templates/wevu-tdesign/tsconfig.app.json +6 -1
  38. package/templates/wevu-tdesign/vite.config.ts +11 -1
  39. package/templates/wevu-tdesign/src/components/HelloWorld/index.vue +0 -23
@@ -5,10 +5,10 @@ import fs2 from "fs-extra";
5
5
  import path2 from "pathe";
6
6
 
7
7
  // ../weapp-vite/package.json
8
- var version = "6.1.6";
8
+ var version = "6.1.7";
9
9
 
10
10
  // ../wevu/package.json
11
- var version2 = "1.0.2";
11
+ var version2 = "1.0.3";
12
12
 
13
13
  // src/enums.ts
14
14
  var TemplateName = /* @__PURE__ */ ((TemplateName2) => {
package/dist/cli.cjs CHANGED
@@ -51,10 +51,10 @@ var import_fs_extra2 = __toESM(require("fs-extra"), 1);
51
51
  var import_pathe2 = __toESM(require("pathe"), 1);
52
52
 
53
53
  // ../weapp-vite/package.json
54
- var version = "6.1.6";
54
+ var version = "6.1.7";
55
55
 
56
56
  // ../wevu/package.json
57
- var version2 = "1.0.2";
57
+ var version2 = "1.0.3";
58
58
 
59
59
  // src/npm.ts
60
60
  var import_node_https = __toESM(require("https"), 1);
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createProject
3
- } from "./chunk-CP2T5O3U.js";
3
+ } from "./chunk-KDUDSVZ5.js";
4
4
 
5
5
  // src/cli.ts
6
6
  import path from "path";
package/dist/index.cjs CHANGED
@@ -46,10 +46,10 @@ var import_fs_extra2 = __toESM(require("fs-extra"), 1);
46
46
  var import_pathe2 = __toESM(require("pathe"), 1);
47
47
 
48
48
  // ../weapp-vite/package.json
49
- var version = "6.1.6";
49
+ var version = "6.1.7";
50
50
 
51
51
  // ../wevu/package.json
52
- var version2 = "1.0.2";
52
+ var version2 = "1.0.3";
53
53
 
54
54
  // src/enums.ts
55
55
  var TemplateName = /* @__PURE__ */ ((TemplateName2) => {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  TemplateName,
3
3
  createProject
4
- } from "./chunk-CP2T5O3U.js";
4
+ } from "./chunk-KDUDSVZ5.js";
5
5
  export {
6
6
  TemplateName,
7
7
  createProject
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-weapp-vite",
3
3
  "type": "module",
4
- "version": "1.3.2",
4
+ "version": "1.3.3",
5
5
  "description": "create-weapp-vite",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -2,6 +2,11 @@
2
2
 
3
3
  `weapp-vite` + `wevu`(Vue SFC)模板
4
4
 
5
+ ## 页面结构
6
+
7
+ - TabBar:`首页` / `数据` / `表单` / `清单` / `能力`
8
+ - 子包:`组件实验室`(subpackages/lab)与 `API 场景`(subpackages/ability)
9
+
5
10
  ## 使用方式
6
11
 
7
12
  ### 开发
@@ -3,7 +3,7 @@
3
3
  // oxlint-disable
4
4
  // ------
5
5
  // Generated by weapp-vite autoImportComponents
6
- import type { ComponentOptionsMixin, DefineComponent, PublicProps } from 'vue'
6
+ import type { ComponentOptionsMixin, DefineComponent, PublicProps } from 'wevu'
7
7
  import type { ComponentProp } from 'weapp-vite/typed-components'
8
8
 
9
9
  export {}
@@ -4,12 +4,65 @@ import { onHide, onLaunch, onShow } from 'wevu'
4
4
  defineAppJson({
5
5
  pages: [
6
6
  'pages/index/index',
7
+ 'pages/data/index',
8
+ 'pages/form/index',
9
+ 'pages/list/index',
10
+ 'pages/ability/index',
7
11
  ],
8
12
  window: {
9
- navigationBarTitleText: 'Wepp-Vite + WeVU Template',
10
- navigationBarBackgroundColor: '#4c6ef5',
13
+ navigationBarTitleText: 'Weapp Studio',
14
+ navigationBarBackgroundColor: '#2f2b5f',
11
15
  navigationBarTextStyle: 'white',
16
+ backgroundTextStyle: 'dark',
12
17
  },
18
+ tabBar: {
19
+ color: '#7a7aa0',
20
+ selectedColor: '#2f2b5f',
21
+ backgroundColor: '#ffffff',
22
+ borderStyle: 'white',
23
+ list: [
24
+ {
25
+ pagePath: 'pages/index/index',
26
+ text: '首页',
27
+ iconPath: 'tabbar/home.png',
28
+ selectedIconPath: 'tabbar/home-active.png',
29
+ },
30
+ {
31
+ pagePath: 'pages/data/index',
32
+ text: '数据',
33
+ iconPath: 'tabbar/data.png',
34
+ selectedIconPath: 'tabbar/data-active.png',
35
+ },
36
+ {
37
+ pagePath: 'pages/form/index',
38
+ text: '表单',
39
+ iconPath: 'tabbar/form.png',
40
+ selectedIconPath: 'tabbar/form-active.png',
41
+ },
42
+ {
43
+ pagePath: 'pages/list/index',
44
+ text: '清单',
45
+ iconPath: 'tabbar/list.png',
46
+ selectedIconPath: 'tabbar/list-active.png',
47
+ },
48
+ {
49
+ pagePath: 'pages/ability/index',
50
+ text: '能力',
51
+ iconPath: 'tabbar/ability.png',
52
+ selectedIconPath: 'tabbar/ability-active.png',
53
+ },
54
+ ],
55
+ },
56
+ subPackages: [
57
+ {
58
+ root: 'subpackages/lab',
59
+ pages: ['index'],
60
+ },
61
+ {
62
+ root: 'subpackages/ability',
63
+ pages: ['index'],
64
+ },
65
+ ],
13
66
  style: 'v2',
14
67
  componentFramework: 'glass-easel',
15
68
  sitemapLocation: 'sitemap.json',
@@ -32,4 +85,9 @@ onLaunch(() => {
32
85
  @tailwind base;
33
86
  @tailwind components;
34
87
  @tailwind utilities;
88
+
89
+ page {
90
+ font-family: 'HarmonyOS Sans', 'PingFang SC', 'Microsoft YaHei', sans-serif;
91
+ background-color: #f6f7fb;
92
+ }
35
93
  </style>
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ const props = withDefaults(
3
+ defineProps<{
4
+ title: string
5
+ description?: string
6
+ actionText?: string
7
+ }>(),
8
+ {
9
+ description: '',
10
+ actionText: '',
11
+ },
12
+ )
13
+
14
+ const emit = defineEmits<{
15
+ (e: 'action'): void
16
+ }>()
17
+
18
+ defineComponentJson({
19
+ styleIsolation: 'apply-shared',
20
+ })
21
+
22
+ function onAction() {
23
+ emit('action')
24
+ }
25
+ </script>
26
+
27
+ <template>
28
+ <view class="rounded-[20rpx] bg-white p-[24rpx] shadow-[0_12rpx_28rpx_rgba(17,24,39,0.08)]">
29
+ <t-empty :title="title" :description="description" />
30
+ <view v-if="props.actionText" class="mt-[16rpx]">
31
+ <t-button block theme="primary" variant="outline" @tap="onAction">
32
+ {{ props.actionText }}
33
+ </t-button>
34
+ </view>
35
+ </view>
36
+ </template>
@@ -0,0 +1,63 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'wevu'
3
+
4
+ const emit = defineEmits<{
5
+ (e: 'update:query', value: string): void
6
+ (e: 'update:active', value: string): void
7
+ }>()
8
+
9
+ const props = defineProps({
10
+ query: { type: String, default: '' },
11
+ active: { type: String, default: 'all' },
12
+ filters: { type: Array, default: () => [] },
13
+ }) as {
14
+ query: string
15
+ active: string
16
+ filters: FilterItem[]
17
+ }
18
+
19
+ defineComponentJson({
20
+ styleIsolation: 'apply-shared',
21
+ })
22
+
23
+ interface FilterItem {
24
+ value: string
25
+ label: string
26
+ count?: number
27
+ }
28
+
29
+ const filterItems = computed(() => (Array.isArray(props.filters) ? props.filters : []))
30
+
31
+ function onQueryChange(e: WechatMiniprogram.CustomEvent<{ value: string }>) {
32
+ emit('update:query', e.detail.value)
33
+ }
34
+
35
+ function onSelect(value: string) {
36
+ emit('update:active', value)
37
+ }
38
+ </script>
39
+
40
+ <template>
41
+ <view class="rounded-[20rpx] bg-white p-[16rpx] shadow-[0_12rpx_28rpx_rgba(17,24,39,0.08)]">
42
+ <t-search
43
+ placeholder="搜索标题或负责人"
44
+ :value="query"
45
+ clearable
46
+ @change="onQueryChange"
47
+ />
48
+ <view class="mt-[12rpx] flex flex-wrap gap-[12rpx]">
49
+ <t-check-tag
50
+ v-for="item in filterItems"
51
+ :key="item.value"
52
+ :checked="item.value === active"
53
+ content=""
54
+ @change="onSelect(item.value)"
55
+ >
56
+ {{ item.label }}
57
+ <text v-if="item.count !== undefined">
58
+ ({{ item.count }})
59
+ </text>
60
+ </t-check-tag>
61
+ </view>
62
+ </view>
63
+ </template>
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'wevu'
3
+
4
+ const props = withDefaults(
5
+ defineProps<{
6
+ label: string
7
+ align?: 'left' | 'center' | 'right'
8
+ description?: string
9
+ }>(),
10
+ {
11
+ align: 'left',
12
+ description: '',
13
+ },
14
+ )
15
+
16
+ defineComponentJson({
17
+ styleIsolation: 'apply-shared',
18
+ })
19
+
20
+ const labelClass = computed(() => {
21
+ if (props.align === 'right') {
22
+ return 'text-right'
23
+ }
24
+ if (props.align === 'center') {
25
+ return 'text-center'
26
+ }
27
+ return 'text-left'
28
+ })
29
+ </script>
30
+
31
+ <template>
32
+ <view class="flex flex-col gap-[8rpx]">
33
+ <view class="flex items-baseline justify-between gap-[12rpx]">
34
+ <text class="text-[22rpx] font-semibold text-[#1f1a3f]" :class="labelClass">
35
+ {{ label }}
36
+ </text>
37
+ <text v-if="description" class="text-[20rpx] text-[#8a8aa5]">
38
+ {{ description }}
39
+ </text>
40
+ </view>
41
+ <slot />
42
+ </view>
43
+ </template>
@@ -0,0 +1,48 @@
1
+ <script setup lang="ts">
2
+ defineOptions({
3
+ options: {
4
+ multipleSlots: true,
5
+ },
6
+ })
7
+
8
+ withDefaults(
9
+ defineProps<{
10
+ step: number
11
+ title: string
12
+ subtitle?: string
13
+ active?: boolean
14
+ }>(),
15
+ {
16
+ subtitle: '',
17
+ active: false,
18
+ },
19
+ )
20
+
21
+ defineComponentJson({
22
+ styleIsolation: 'apply-shared',
23
+ })
24
+ </script>
25
+
26
+ <template>
27
+ <view class="rounded-[20rpx] bg-white p-[20rpx] shadow-[0_12rpx_28rpx_rgba(17,24,39,0.08)]">
28
+ <view class="flex items-center gap-[12rpx]">
29
+ <view
30
+ class="flex h-[36rpx] w-[36rpx] items-center justify-center rounded-full text-[20rpx] font-semibold"
31
+ :class="active ? 'bg-[#2f2b5f] text-white' : 'bg-[#eff1f6] text-[#5c5b7a]'"
32
+ >
33
+ {{ step }}
34
+ </view>
35
+ <view>
36
+ <text class="text-[26rpx] font-semibold text-[#1f1a3f]">
37
+ {{ title }}
38
+ </text>
39
+ <text v-if="subtitle" class="mt-[4rpx] block text-[20rpx] text-[#6f6b8a]">
40
+ {{ subtitle }}
41
+ </text>
42
+ </view>
43
+ </view>
44
+ <view class="mt-[16rpx]">
45
+ <slot />
46
+ </view>
47
+ </view>
48
+ </template>
@@ -0,0 +1,146 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'wevu'
3
+
4
+ defineOptions({
5
+ options: {
6
+ multipleSlots: true,
7
+ },
8
+ })
9
+
10
+ const props = defineProps({
11
+ title: { type: String, required: true },
12
+ subtitle: { type: String, default: '' },
13
+ items: { type: null, default: () => [] },
14
+ columns: { type: Number, default: 2 },
15
+ }) as {
16
+ title: string
17
+ subtitle?: string
18
+ items?: KpiItem[]
19
+ columns?: 2 | 3
20
+ }
21
+
22
+ defineComponentJson({
23
+ styleIsolation: 'apply-shared',
24
+ })
25
+
26
+ type KpiTone = 'positive' | 'negative' | 'neutral'
27
+
28
+ export interface KpiItem {
29
+ key?: string
30
+ label: string
31
+ value: string | number
32
+ unit?: string
33
+ delta?: number
34
+ footnote?: string
35
+ }
36
+
37
+ const cards = computed(() => {
38
+ const source = Array.isArray(props.items) ? props.items : []
39
+ return source.map((item, index) => ({
40
+ key: item.key ?? String(index),
41
+ item,
42
+ index,
43
+ tone: resolveTone(item.delta),
44
+ isLeading: index === 0,
45
+ }))
46
+ })
47
+
48
+ const gridClass = computed(() => (props.columns === 3 ? 'grid-cols-3' : 'grid-cols-2'))
49
+
50
+ function resolveTone(delta?: number): KpiTone {
51
+ if (delta === undefined || Number.isNaN(delta)) {
52
+ return 'neutral'
53
+ }
54
+ if (delta > 0) {
55
+ return 'positive'
56
+ }
57
+ if (delta < 0) {
58
+ return 'negative'
59
+ }
60
+ return 'neutral'
61
+ }
62
+
63
+ function formatDelta(delta?: number, unit = '') {
64
+ if (delta === undefined || Number.isNaN(delta)) {
65
+ return '--'
66
+ }
67
+ const sign = delta > 0 ? '+' : ''
68
+ return `${sign}${delta}${unit}`
69
+ }
70
+
71
+ function toneBadgeClass(tone: KpiTone) {
72
+ if (tone === 'positive') {
73
+ return 'bg-[#e7f7ee] text-[#1b7a3a]'
74
+ }
75
+ if (tone === 'negative') {
76
+ return 'bg-[#ffe9e9] text-[#b42318]'
77
+ }
78
+ return 'bg-[#edf1f7] text-[#64748b]'
79
+ }
80
+
81
+ function toneDotClass(tone: KpiTone) {
82
+ if (tone === 'positive') {
83
+ return 'bg-[#22c55e]'
84
+ }
85
+ if (tone === 'negative') {
86
+ return 'bg-[#ef4444]'
87
+ }
88
+ return 'bg-[#94a3b8]'
89
+ }
90
+ </script>
91
+
92
+ <template>
93
+ <view class="rounded-[24rpx] bg-white p-[20rpx] shadow-[0_18rpx_40rpx_rgba(17,24,39,0.08)]">
94
+ <view class="flex items-end justify-between">
95
+ <view>
96
+ <text class="text-[28rpx] font-semibold text-[#1f1a3f]">
97
+ {{ title }}
98
+ </text>
99
+ <text v-if="subtitle" class="mt-[6rpx] block text-[22rpx] text-[#6f6b8a]">
100
+ {{ subtitle }}
101
+ </text>
102
+ </view>
103
+ <slot name="action" />
104
+ </view>
105
+ <view class="mt-[16rpx] grid gap-[12rpx]" :class="gridClass">
106
+ <slot name="items" :items="cards">
107
+ <view v-for="card in cards" :key="card.key">
108
+ <view class="rounded-[18rpx] bg-[#f7f7fb] p-[16rpx]">
109
+ <view class="flex items-center justify-between">
110
+ <view class="flex items-center gap-[8rpx]">
111
+ <view class="h-[8rpx] w-[8rpx] rounded-full" :class="toneDotClass(card.tone)" />
112
+ <text class="text-[22rpx] text-[#61618a]">
113
+ {{ card.item.label }}
114
+ </text>
115
+ </view>
116
+ <view v-if="card.isLeading" class="rounded-full bg-[#fff3c2] px-[10rpx] py-[4rpx]">
117
+ <text class="text-[18rpx] font-semibold text-[#8a5200]">
118
+ HOT
119
+ </text>
120
+ </view>
121
+ </view>
122
+ <view class="mt-[10rpx] flex items-end justify-between">
123
+ <view class="flex items-baseline gap-[6rpx]">
124
+ <text class="text-[32rpx] font-bold text-[#1c1c3c]">
125
+ {{ card.item.value }}
126
+ </text>
127
+ <text v-if="card.item.unit" class="text-[20rpx] text-[#7a7aa0]">
128
+ {{ card.item.unit }}
129
+ </text>
130
+ </view>
131
+ <view class="rounded-full px-[10rpx] py-[4rpx]" :class="toneBadgeClass(card.tone)">
132
+ <text class="text-[20rpx] font-semibold">
133
+ {{ card.tone === 'positive' ? '↑' : card.tone === 'negative' ? '↓' : '→' }}
134
+ {{ formatDelta(card.item.delta, card.item.unit ?? '') }}
135
+ </text>
136
+ </view>
137
+ </view>
138
+ <text v-if="card.item.footnote" class="mt-[6rpx] block text-[20rpx] text-[#8a8aa5]">
139
+ {{ card.item.footnote }}
140
+ </text>
141
+ </view>
142
+ </view>
143
+ </slot>
144
+ </view>
145
+ </view>
146
+ </template>
@@ -0,0 +1,90 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'wevu'
3
+
4
+ const emit = defineEmits<{
5
+ (e: 'select', item: ActionItem): void
6
+ }>()
7
+
8
+ const props = defineProps({
9
+ title: { type: String, required: true },
10
+ subtitle: { type: String, default: '' },
11
+ items: { type: null, default: () => [] },
12
+ }) as {
13
+ title: string
14
+ subtitle?: string
15
+ items?: ActionItem[]
16
+ }
17
+
18
+ defineComponentJson({
19
+ styleIsolation: 'apply-shared',
20
+ })
21
+
22
+ interface ActionItem {
23
+ key: string
24
+ title: string
25
+ description?: string
26
+ icon?: string
27
+ tag?: string
28
+ tone?: 'brand' | 'neutral'
29
+ disabled?: boolean
30
+ path?: string
31
+ type?: 'tab' | 'sub'
32
+ }
33
+
34
+ const cards = computed(() => (Array.isArray(props.items) ? props.items : []))
35
+
36
+ function onSelect(item: ActionItem) {
37
+ if (item.disabled) {
38
+ return
39
+ }
40
+ emit('select', item)
41
+ }
42
+
43
+ function toneClass(tone?: 'brand' | 'neutral') {
44
+ if (tone === 'brand') {
45
+ return 'bg-[#eef2ff] text-[#3534a5]'
46
+ }
47
+ return 'bg-[#f2f4f8] text-[#5c5b7a]'
48
+ }
49
+ </script>
50
+
51
+ <template>
52
+ <view class="rounded-[24rpx] bg-white p-[20rpx] shadow-[0_18rpx_40rpx_rgba(17,24,39,0.08)]">
53
+ <view class="flex items-end justify-between">
54
+ <view>
55
+ <text class="text-[28rpx] font-semibold text-[#1f1a3f]">
56
+ {{ title }}
57
+ </text>
58
+ <text v-if="subtitle" class="mt-[6rpx] block text-[22rpx] text-[#6f6b8a]">
59
+ {{ subtitle }}
60
+ </text>
61
+ </view>
62
+ </view>
63
+ <view class="mt-[16rpx] grid grid-cols-2 gap-[12rpx]">
64
+ <view
65
+ v-for="item in cards"
66
+ :key="item.key"
67
+ class="rounded-[18rpx] bg-[#f7f7fb] p-[16rpx]"
68
+ :class="item.disabled ? 'opacity-50' : 'opacity-100'"
69
+ @tap="onSelect(item)"
70
+ >
71
+ <view class="flex items-center justify-between">
72
+ <view class="flex items-center gap-[8rpx]">
73
+ <view class="flex h-[36rpx] w-[36rpx] items-center justify-center rounded-[12rpx]" :class="toneClass(item.tone)">
74
+ <t-icon :name="item.icon ?? 'app'" size="22" />
75
+ </view>
76
+ <text class="text-[24rpx] font-semibold text-[#1f1a3f]">
77
+ {{ item.title }}
78
+ </text>
79
+ </view>
80
+ <t-tag v-if="item.tag" size="small" theme="primary" variant="light">
81
+ {{ item.tag }}
82
+ </t-tag>
83
+ </view>
84
+ <text v-if="item.description" class="mt-[10rpx] block text-[20rpx] text-[#6f6b8a]">
85
+ {{ item.description }}
86
+ </text>
87
+ </view>
88
+ </view>
89
+ </view>
90
+ </template>
@@ -0,0 +1,51 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'wevu'
3
+
4
+ defineOptions({
5
+ options: {
6
+ multipleSlots: true,
7
+ },
8
+ })
9
+
10
+ const props = withDefaults(
11
+ defineProps<{
12
+ title: string
13
+ items?: ResultItem[]
14
+ }>(),
15
+ {
16
+ items: () => [],
17
+ },
18
+ )
19
+
20
+ defineComponentJson({
21
+ styleIsolation: 'apply-shared',
22
+ })
23
+
24
+ interface ResultItem {
25
+ label: string
26
+ value: string | number
27
+ }
28
+
29
+ const rows = computed(() => props.items ?? [])
30
+ </script>
31
+
32
+ <template>
33
+ <view class="rounded-[20rpx] bg-white p-[20rpx] shadow-[0_12rpx_28rpx_rgba(17,24,39,0.08)]">
34
+ <view class="flex items-center justify-between">
35
+ <text class="text-[26rpx] font-semibold text-[#1f1a3f]">
36
+ {{ title }}
37
+ </text>
38
+ <slot name="action" />
39
+ </view>
40
+ <view class="mt-[12rpx] space-y-[10rpx]">
41
+ <view v-for="row in rows" :key="row.label" class="flex items-center justify-between">
42
+ <text class="text-[22rpx] text-[#6f6b8a]">
43
+ {{ row.label }}
44
+ </text>
45
+ <text class="text-[22rpx] font-semibold text-[#1f1a3f]">
46
+ {{ row.value }}
47
+ </text>
48
+ </view>
49
+ </view>
50
+ </view>
51
+ </template>