officialblock 1.0.8 → 1.1.0

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 (42) hide show
  1. package/dist/official-block.cjs.js +1 -1
  2. package/dist/official-block.es.js +55 -23
  3. package/dist/official-block.umd.js +1 -1
  4. package/dist/style.css +1 -1
  5. package/package.json +1 -1
  6. package/src/assets/icon-email.svg +3 -0
  7. package/src/components/ArticleList/setting.vue +316 -142
  8. package/src/components/BannerImageWithLink/index.ts +11 -0
  9. package/src/components/BannerImageWithLink/index.vue +323 -0
  10. package/src/components/BannerImageWithLink/setting.vue +344 -0
  11. package/src/components/BannerImageWithLink/type.ts +17 -0
  12. package/src/components/ContactUsList/index.ts +11 -0
  13. package/src/components/ContactUsList/index.vue +369 -0
  14. package/src/components/ContactUsList/setting.vue +497 -0
  15. package/src/components/ContactUsList/type.ts +17 -0
  16. package/src/components/CountDown/index.ts +11 -0
  17. package/src/components/CountDown/index.vue +315 -0
  18. package/src/components/CountDown/setting.vue +302 -0
  19. package/src/components/CountDown/type.ts +17 -0
  20. package/src/components/CustomIframe/index.ts +11 -0
  21. package/src/components/CustomIframe/index.vue +118 -0
  22. package/src/components/CustomIframe/setting.vue +323 -0
  23. package/src/components/CustomIframe/type.ts +17 -0
  24. package/src/components/Operate/index.vue +1 -2
  25. package/src/components/QuoteText/index.vue +4 -4
  26. package/src/components/ScrollKeyInfo/index.ts +11 -0
  27. package/src/components/ScrollKeyInfo/index.vue +1345 -0
  28. package/src/components/ScrollKeyInfo/setting.vue +302 -0
  29. package/src/components/ScrollKeyInfo/type.ts +17 -0
  30. package/src/components/TabDefault/components/ComponentSelector/compsData.js +143 -0
  31. package/src/components/TabDefault/components/ComponentSelector/index.vue +188 -0
  32. package/src/components/TabDefault/components/PageContent.vue +207 -0
  33. package/src/components/TabDefault/index.vue +475 -0
  34. package/src/components/TabDefault/setting.vue +581 -0
  35. package/src/components/TabDefault/type.ts +17 -0
  36. package/src/components/TableTwo/index.ts +11 -0
  37. package/src/components/TableTwo/index.vue +232 -0
  38. package/src/components/TableTwo/setting.vue +558 -0
  39. package/src/components/TableTwo/type.ts +17 -0
  40. package/src/components/index.ts +17 -0
  41. package/src/styles/component-isolation.scss +2 -1
  42. package/src/views/components/ArticleListDemo.vue +50 -49
@@ -0,0 +1,315 @@
1
+ <template>
2
+ <div
3
+ style="margin-top: 30px; margin-bottom: 30px"
4
+ class="count-down-container"
5
+ :style="{ backgroundColor: modelValue?.bgColor }"
6
+ @mouseenter="isHover = true"
7
+ @mouseleave="isHover = false"
8
+ >
9
+ <!-- <a-row
10
+ class="count_down"
11
+ :class="[
12
+ modelValue?.width
13
+ ? `container-content-${modelValue?.width}`
14
+ : 'container-content',
15
+ ]"
16
+ > -->
17
+ <div class="count-down">
18
+ <div class="count-down__wrapper container-content">
19
+ <div class="count-down__img">
20
+ <img
21
+ src="https://osswebsite-test.cedim.cn/media-library/shared/24-25%E5%BC%80%E5%AD%A6/0207/640-1_origin_origin.jpg"
22
+ alt="ding-alt"
23
+ />
24
+ </div>
25
+ <div class="count-down__content">
26
+ <div class="content__text">
27
+ <p>{{ modelValue?.content }}</p>
28
+ </div>
29
+ <div class="content__title">{{ modelValue?.title }}</div>
30
+ </div>
31
+ <ul class="count-down__timer">
32
+ <li>
33
+ <div class="count-down__timer__time">{{ timeObj?.day }}</div>
34
+ <div class="count-down__timer__label">日</div>
35
+ </li>
36
+ <li>
37
+ <div class="count-down__timer__time">{{ timeObj?.hour }}</div>
38
+ <div class="count-down__timer__label">小时</div>
39
+ </li>
40
+ <li>
41
+ <div class="count-down__timer__time">{{ timeObj?.min }}</div>
42
+ <div class="count-down__timer__label">分钟</div>
43
+ </li>
44
+ <li>
45
+ <div class="count-down__timer__time">{{ timeObj?.sec }}</div>
46
+ <div class="count-down__timer__label">秒</div>
47
+ </li>
48
+ </ul>
49
+ </div>
50
+ </div>
51
+ <!-- 左侧文本 后侧媒体 -->
52
+ <!-- 左侧一直是一半,但只有左侧时是100% -->
53
+ <!-- <a-col :sm="{ span: 24 }" :md="{ span: hasMedia ? 12 : 24 }"> </a-col>
54
+ <a-col v-if="hasMedia" :sm="{ span: 24 }" :md="{ span: 12 }"> </a-col> -->
55
+ <!-- -->
56
+ <Operate
57
+ v-if="!modelValue?.readOnly"
58
+ v-model:show="isHover"
59
+ @handle-edit="showSetting = true"
60
+ @handle-delete="handleDelete"
61
+ @handle-copy="handleCopy"
62
+ ></Operate>
63
+ <!-- </a-row> -->
64
+ </div>
65
+
66
+ <Setting v-model:show="showSetting" :data="modelValue"></Setting>
67
+ </template>
68
+
69
+ <script lang="ts" setup>
70
+ import { computed, nextTick, ref } from "vue";
71
+ import { randomString } from "@/utils/common";
72
+ import Setting from "./setting.vue";
73
+ import Operate from "@/components/Operate/index.vue";
74
+
75
+ // 定义组件名称
76
+ defineOptions({
77
+ name: "CountDown",
78
+ });
79
+
80
+ const props = defineProps({
81
+ modelValue: {
82
+ type: Object,
83
+ default: () => {},
84
+ },
85
+
86
+ // 是否预览
87
+ isPreview: {
88
+ type: Boolean,
89
+ default: false,
90
+ },
91
+ });
92
+ console.log("!!!!", props.modelValue);
93
+ const emit = defineEmits(["update:modelValue", "handleDelete", "handleCopy"]);
94
+
95
+ const isHover = ref<boolean>(false);
96
+ const showSetting = ref<boolean>(false);
97
+ const timeObj = ref({
98
+ day: 0,
99
+ hour: 0,
100
+ min: 0,
101
+ sec: 0,
102
+ });
103
+ // const timer = null;
104
+ const timer = ref(null);
105
+
106
+ const handleDelete = () => {
107
+ emit("handleDelete", props.modelValue.id);
108
+ };
109
+
110
+ const handleCopy = () => {
111
+ emit("handleCopy", props.modelValue);
112
+ };
113
+
114
+ const handleInit = () => {
115
+ if (props.modelValue && props.modelValue.data) return; // 有数据不用初始化
116
+ const data = {
117
+ id: props.modelValue?.id || randomString(),
118
+ type: "CountDown",
119
+ readOnly: props.modelValue?.readOnly || false,
120
+ title: "ding-title",
121
+ content: "ding-content",
122
+ countTime: "2025-08-08",
123
+ imgSrc:
124
+ "https://osswebsite.ycyw.com/media-library/ywies-bj/images/home/ywies-tx.jpg",
125
+ // width: "",
126
+ // bgColor: "",
127
+ };
128
+ emit("update:modelValue", data);
129
+ nextTick(() => {
130
+ countDown();
131
+ });
132
+ };
133
+ // 根据现在的时间(年月日时分秒)到modelValue中的countTime的倒计时,并赋值给timeObj中,要求一直倒计时
134
+ const countDown = () => {
135
+ if (timer.value) {
136
+ clearInterval(timer.value);
137
+ }
138
+ timer.value = setInterval(() => {
139
+ const now = new Date();
140
+ const countTime = new Date(props.modelValue.countTime);
141
+ const diff = countTime - now;
142
+ if (diff <= 0) return;
143
+ timeObj.value.day = Math.floor(diff / (1000 * 60 * 60 * 24));
144
+ timeObj.value.hour = Math.floor((diff / (1000 * 60 * 60)) % 24);
145
+ timeObj.value.min = Math.floor((diff / (1000 * 60)) % 60);
146
+ timeObj.value.sec = Math.floor((diff / 1000) % 60);
147
+ //四个时间都等于0,取消定时器
148
+ if (
149
+ timeObj.value.day === 0 &&
150
+ timeObj.value.hour === 0 &&
151
+ timeObj.value.min === 0 &&
152
+ timeObj.value.sec === 0
153
+ ) {
154
+ clearInterval(timer.value!);
155
+ timer.value = null;
156
+ }
157
+ }, 1000);
158
+ };
159
+
160
+ handleInit();
161
+ </script>
162
+
163
+ <style lang="scss" scoped>
164
+ .count-down {
165
+ position: relative;
166
+ }
167
+ .count-down-container {
168
+ text-align: center;
169
+ display: block;
170
+ position: relative;
171
+ }
172
+ .count-down__wrapper {
173
+ display: flex;
174
+ flex-direction: column;
175
+ align-items: center;
176
+ }
177
+
178
+ .count-down__img {
179
+ width: 127.14px;
180
+ height: 100px;
181
+ margin-bottom: 25.06px;
182
+ }
183
+
184
+ @media (max-width: 767.98px) {
185
+ .count-down__img {
186
+ width: 101.7px;
187
+ height: 80px;
188
+ margin-bottom: 24px;
189
+ }
190
+ }
191
+
192
+ .count-down__img img {
193
+ width: 100%;
194
+ height: 100%;
195
+ -o-object-fit: contain;
196
+ object-fit: contain;
197
+ }
198
+
199
+ .count-down__content {
200
+ margin-bottom: 24px;
201
+ max-width: 620px;
202
+ }
203
+
204
+ @media (max-width: 767.98px) {
205
+ .count-down__content {
206
+ padding-left: 24px;
207
+ padding-right: 24px;
208
+ }
209
+ }
210
+
211
+ .count-down__content .content__text {
212
+ font-size: 14px;
213
+ line-height: 1.2857;
214
+ letter-spacing: 0.04em;
215
+ color: #64788f;
216
+ text-align: center;
217
+ margin-bottom: 8px;
218
+ }
219
+
220
+ .count-down__content .content__title {
221
+ font-size: 16px;
222
+ font-weight: 700;
223
+ line-height: 1.25;
224
+ letter-spacing: 0.1em;
225
+ color: #0048e8;
226
+ text-align: center;
227
+ }
228
+
229
+ @media (max-width: 1023.98px) {
230
+ .count-down__content .content__title {
231
+ font-size: 14px;
232
+ line-height: 1.714;
233
+ }
234
+ }
235
+
236
+ @media (max-width: 767.98px) {
237
+ .count-down__content .content__title {
238
+ line-height: 1.428;
239
+ }
240
+ }
241
+
242
+ .count-down__timer,
243
+ .count-down__timer li {
244
+ display: flex;
245
+ align-items: center;
246
+ }
247
+
248
+ .count-down__timer li {
249
+ flex-direction: column;
250
+ }
251
+
252
+ .count-down__timer li:not(:first-child) {
253
+ padding-left: 48.83px;
254
+ border-left: 1px solid #e4e4e6;
255
+ }
256
+
257
+ @media (max-width: 1023.98px) {
258
+ .count-down__timer li:not(:first-child) {
259
+ padding-left: 25.83px;
260
+ }
261
+ }
262
+
263
+ @media (max-width: 767.98px) {
264
+ .count-down__timer li:not(:first-child) {
265
+ padding-left: 13.83px;
266
+ }
267
+ }
268
+
269
+ .count-down__timer li:not(:last-child) {
270
+ padding-right: 48.83px;
271
+ }
272
+
273
+ @media (max-width: 1023.98px) {
274
+ .count-down__timer li:not(:last-child) {
275
+ padding-right: 25.83px;
276
+ }
277
+ }
278
+
279
+ @media (max-width: 767.98px) {
280
+ .count-down__timer li:not(:last-child) {
281
+ padding-right: 13.83px;
282
+ }
283
+ }
284
+
285
+ .count-down__timer__time {
286
+ font-size: 80px;
287
+ line-height: 1;
288
+ font-weight: 300;
289
+ letter-spacing: 0.08em;
290
+ color: #0048e8;
291
+ margin-bottom: 11px;
292
+ }
293
+
294
+ @media (max-width: 767.98px) {
295
+ .count-down__timer__time {
296
+ font-size: 36px;
297
+ margin-bottom: 4px;
298
+ }
299
+ }
300
+
301
+ .count-down__timer__label {
302
+ font-size: 20px;
303
+ line-height: 0.8;
304
+ font-weight: 300;
305
+ letter-spacing: 0.06em;
306
+ color: #82828c;
307
+ }
308
+
309
+ @media (max-width: 767.98px) {
310
+ .count-down__timer__label {
311
+ font-size: 12px;
312
+ line-height: 1.33;
313
+ }
314
+ }
315
+ </style>
@@ -0,0 +1,302 @@
1
+ <template>
2
+ <a-drawer
3
+ :width="500"
4
+ :visible="show"
5
+ :footer="false"
6
+ @cancel="handleCancel"
7
+ unmountOnClose
8
+ >
9
+ <template #title> {{ data?.type }}组件编辑 </template>
10
+ <div class="seting-box">
11
+ <p class="item-title">标题</p>
12
+ <a-input v-model="data.title" placeholder="请输入标题" allow-clear />
13
+
14
+ <p class="item-title mt-2">内容</p>
15
+ <RichTextEditor v-model="data.content"></RichTextEditor>
16
+ <p class="item-title">图片</p>
17
+ <img class="item-img" :src="paragraph.imgSrc" />
18
+ <div class="item-uplaod flex items-center">
19
+ <a-input
20
+ v-model="paragraph.imgSrc"
21
+ placeholder="请输入图片链接"
22
+ allow-clear
23
+ />
24
+ <a-upload class="fit-content" :show-file-list="false" action="/" />
25
+ </div>
26
+ </div>
27
+ </a-drawer>
28
+ </template>
29
+
30
+ <script lang="ts" setup>
31
+ import { ref, computed } from "vue";
32
+ import RichTextEditor from "@/components/RichTextEditor";
33
+ import { randomString } from "@/utils/common";
34
+
35
+ const props = defineProps({
36
+ show: {
37
+ type: Boolean,
38
+ default: false,
39
+ },
40
+
41
+ data: {
42
+ type: Object,
43
+ default: () => {},
44
+ },
45
+ });
46
+
47
+ const emit = defineEmits(["update:show"]);
48
+
49
+ const paragraph = ref({
50
+ title: "",
51
+ content: "",
52
+ imgSrc:
53
+ "https://osswebsite.ycyw.com/media-library/ywies-bj/images/home/ywies-tx.jpg",
54
+ });
55
+
56
+ const handleCancel = () => {
57
+ emit("update:show", false);
58
+ };
59
+ </script>
60
+
61
+ <style lang="scss" scoped>
62
+ .item-img {
63
+ height: 100px;
64
+ }
65
+ .seting-box {
66
+ padding: 20px;
67
+ background: #f0f2f5;
68
+ border-radius: 3px;
69
+ .arco-input-wrapper {
70
+ background: #ffffff;
71
+ }
72
+ }
73
+ .setting-content {
74
+ .setting-header {
75
+ padding-bottom: 12px;
76
+
77
+ .header-title {
78
+ width: 120px;
79
+ padding-right: 12px;
80
+ text-align: right;
81
+ }
82
+ }
83
+
84
+ .setting-body {
85
+ margin-top: 12px;
86
+
87
+ .setting-item {
88
+ position: relative;
89
+ padding: 16px 12px;
90
+ background: #f0f2f5;
91
+ border-radius: 8px;
92
+ margin-bottom: 20px;
93
+
94
+ .btn-group {
95
+ position: absolute;
96
+ right: 0;
97
+ top: 0;
98
+ display: flex;
99
+ align-items: center;
100
+ padding: 4px;
101
+
102
+ .btn-delete {
103
+ padding: 4px;
104
+ font-size: 24px;
105
+ cursor: pointer;
106
+ }
107
+ }
108
+
109
+ .item-name {
110
+ font-size: 16px;
111
+ font-weight: 600;
112
+ padding-bottom: 10px;
113
+ border-bottom: 1px solid #fff;
114
+ }
115
+
116
+ .item-title {
117
+ padding: 12px 0 8px 0;
118
+ font-size: 14px;
119
+ font-weight: 600;
120
+ }
121
+
122
+ .arco-input-wrapper {
123
+ background: #fff;
124
+ }
125
+
126
+ .item-button {
127
+ position: relative;
128
+ padding: 12px 8px 4px;
129
+ background: #fff;
130
+ border-radius: 4px;
131
+ margin: 4px 0;
132
+ transition: all 0.3s ease;
133
+
134
+ &.draggable-item {
135
+ cursor: move;
136
+
137
+ &:hover {
138
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
139
+ transform: translateY(-1px);
140
+ }
141
+
142
+ // 当禁用拖拽时,不显示拖拽效果
143
+ &.sortable-disabled {
144
+ cursor: default;
145
+
146
+ &:hover {
147
+ box-shadow: none;
148
+ transform: none;
149
+ }
150
+ }
151
+ }
152
+
153
+ .arco-input-wrapper {
154
+ background: #f2f3f5;
155
+ }
156
+ }
157
+
158
+ // 拖拽相关样式
159
+ .flip-list-move {
160
+ transition: transform 0.5s;
161
+ }
162
+
163
+ .no-move {
164
+ transition: transform 0s;
165
+ }
166
+
167
+ .ghost {
168
+ opacity: 0.5;
169
+ background: #c8ebfb;
170
+ }
171
+
172
+ .list-group {
173
+ min-height: 20px;
174
+ }
175
+
176
+ .list-group-item {
177
+ cursor: move;
178
+ }
179
+
180
+ .list-group-item i {
181
+ cursor: pointer;
182
+ }
183
+
184
+ .item-action {
185
+ padding: 10px 0;
186
+
187
+ .action-text {
188
+ width: 150px;
189
+ margin-right: 8px;
190
+ }
191
+ }
192
+
193
+ .item-add-btn {
194
+ display: inline-block;
195
+ padding: 2px 8px;
196
+ margin-top: 5px;
197
+ font-size: 11px;
198
+ color: #165dff;
199
+ border-radius: 4px;
200
+ font-weight: 600;
201
+ border: 1px solid #165dff;
202
+ cursor: pointer;
203
+ }
204
+
205
+ .item-img {
206
+ margin-top: 12px;
207
+ height: 160px;
208
+ }
209
+
210
+ .fit-content {
211
+ width: fit-content;
212
+ }
213
+
214
+ .item-img-list {
215
+ .img-list-item {
216
+ margin: 4px 0;
217
+ position: relative;
218
+ padding: 8px;
219
+ border-radius: 4px;
220
+ transition: all 0.3s ease;
221
+ background: #fff;
222
+ border-radius: 4px;
223
+
224
+ &.draggable-item {
225
+ cursor: move;
226
+
227
+ &:hover {
228
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
229
+ transform: translateY(-1px);
230
+ }
231
+
232
+ // 当禁用拖拽时,不显示拖拽效果
233
+ &.sortable-disabled {
234
+ cursor: default;
235
+
236
+ &:hover {
237
+ box-shadow: none;
238
+ transform: none;
239
+ }
240
+ }
241
+ }
242
+
243
+ .arco-input-wrapper {
244
+ background: #f2f3f5;
245
+ }
246
+
247
+ .img-drag-handle {
248
+ top: 0 !important;
249
+ }
250
+ }
251
+
252
+ .item-img-box {
253
+ margin-right: 12px;
254
+ position: relative;
255
+ width: 133px;
256
+ height: 100px;
257
+
258
+ .item-img-dlete {
259
+ position: absolute;
260
+ padding: 8px;
261
+ font-size: 32px;
262
+ top: -16px;
263
+ right: -16px;
264
+ color: red;
265
+ cursor: pointer;
266
+ }
267
+ }
268
+
269
+ .small-img {
270
+ margin: 0;
271
+ height: 100px;
272
+ object-fit: cover;
273
+ }
274
+
275
+ .item-right {
276
+ padding-top: 24px;
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ .drag-handle {
283
+ padding: 4px;
284
+ cursor: grab;
285
+ padding: 4px;
286
+ border-radius: 4px;
287
+
288
+ &:hover {
289
+ background-color: #f0f2f5;
290
+ }
291
+
292
+ &:active {
293
+ cursor: grabbing;
294
+ }
295
+
296
+ .drag-icon {
297
+ font-size: 16px;
298
+ color: #86909c;
299
+ }
300
+ }
301
+ }
302
+ </style>
@@ -0,0 +1,17 @@
1
+ export interface CountDownProps {
2
+ /** 双向绑定的值 */
3
+ modelValue: any
4
+ }
5
+
6
+ export interface CountDownEmits {
7
+ (e: 'update:modelValue', value: any): void
8
+ (e: 'handleDelete', value: string | number): void
9
+ (e: 'handleCopy', value: any): void
10
+ }
11
+
12
+ // export type ComponentSlots = {
13
+ // /** 默认插槽内容 */
14
+ // default?: (props: { value: string | number }) => VNode[]
15
+ // /** 头部内容 */
16
+ // header?: (props: { title: string }) => VNode[]
17
+ // }
@@ -0,0 +1,11 @@
1
+ import type { App, Plugin } from 'vue'
2
+ import CustomIframe from './index.vue'
3
+
4
+ export default {
5
+ install: (app: App) => {
6
+ app.component('CustomIframe', CustomIframe)
7
+ },
8
+ } satisfies Plugin
9
+
10
+ export { default as CountDown } from './index.vue'
11
+ export type { CustomIframeProps, CustomIframeEmits } from './type'