p-pc-ui 1.2.2 → 1.2.5

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.
@@ -0,0 +1,40 @@
1
+ <script setup lang="ts">
2
+ import { dataUtils } from '../../../utils';
3
+ import { ref, defineProps, defineEmits } from 'vue';
4
+ const props = defineProps({
5
+ showBack: {
6
+ type: Boolean,
7
+ default: false,
8
+ },
9
+ showHome: {
10
+ type: Boolean,
11
+ default: false,
12
+ },
13
+ backDelta: {
14
+ type: Number,
15
+ default: 1,
16
+ },
17
+ color: {
18
+ type: String,
19
+ default: '#606266',
20
+ },
21
+ });
22
+
23
+ const goBack = () => {
24
+ dataUtils.backTo(props.backDelta);
25
+ };
26
+
27
+ const goHome = () => {
28
+ dataUtils.dirTo('/pages/start/start');
29
+ };
30
+ </script>
31
+
32
+ <template>
33
+ <view v-if="showBack || showHome"
34
+ style="margin-left: 20rpx; display: flex; align-items: center; justify-content: space-between">
35
+ <u-icon v-if="showBack" @click="goBack" name="arrow-left" size="20" :color="color"></u-icon>
36
+ <u-icon v-if="showHome" @click="goHome" name="home" size="25" :color="color"></u-icon>
37
+ </view>
38
+ </template>
39
+
40
+ <style scoped lang="scss"></style>
@@ -0,0 +1,212 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ ref,
4
+ defineProps,
5
+ defineEmits,
6
+ useSlots,
7
+ reactive,
8
+ onBeforeMount,
9
+ } from 'vue';
10
+ import BackButton from './components/back-button.vue';
11
+ import PPageLoading from '../p-page-loading/p-page-loading.vue';
12
+
13
+ const emits = defineEmits(['refresh', 'lodeMore', 'pageRenderOk', 'authClose']);
14
+ const uSlots = useSlots();
15
+
16
+ interface Props {
17
+ title?: string;
18
+ pageLoading?: boolean;
19
+ hasHeader?: boolean;
20
+ hasScrollBody?: boolean;
21
+ pageBackgroundColor?: string;
22
+ headerBackgroundColor?: string;
23
+ bodyBackgroundColor?: string;
24
+ footerBackgroundColor?: string;
25
+ titleColor?: string;
26
+ titleWeight?: number;
27
+ showBack?: boolean;
28
+ showHome?: boolean;
29
+ backDelta?: number;
30
+ checkSafeBottom?: boolean;
31
+ isTabBarPage?: boolean;
32
+ refresh?: Function;
33
+ }
34
+
35
+ const props = withDefaults(defineProps<Props>(), {
36
+ title: '',
37
+ pageLoading: false,
38
+ hasHeader: true,
39
+ hasScrollBody: true,
40
+ pageBackgroundColor: '#ffffff',
41
+ headerBackgroundColor: 'rgba(0,0,0,0)',
42
+ bodyBackgroundColor: 'rgba(0,0,0,0)',
43
+ footerBackgroundColor: 'rgba(0,0,0,0)',
44
+ titleColor: '#272727',
45
+ titleWeight: 500,
46
+ showBack: true,
47
+ showHome: true,
48
+ backDelta: 1,
49
+ checkSafeBottom: true,
50
+ isTabBarPage: false,
51
+ });
52
+
53
+ const pageHeight = ref('100%');
54
+ const headerHeight = ref(44);
55
+ const statusBarHeight = ref(44);
56
+
57
+ const triggered = ref(false);
58
+
59
+ // 页面堆栈数, 如果只有一页的话 需要自动展示home按钮
60
+
61
+ const pageShowHome = ref(false);
62
+ const pageShowBack = ref(false);
63
+
64
+ // 是否需要底部安全距离
65
+ const footer_safe_distance = ref(props.isTabBarPage ? 0 : 20);
66
+
67
+ onBeforeMount(() => {
68
+ init();
69
+ });
70
+
71
+ const init = () => {
72
+ // 计算状态栏高度
73
+ const systemInfo: any = uni.getSystemInfoSync();
74
+ // #ifdef H5
75
+ statusBarHeight.value = 44
76
+ // #endif
77
+
78
+ // #ifndef H5
79
+ statusBarHeight.value = systemInfo.statusBarHeight;
80
+ // #endif
81
+
82
+ headerHeight.value += statusBarHeight.value;
83
+ pageHeight.value = systemInfo.windowHeight + 'px';
84
+
85
+ // 初始化返回状态
86
+ const pages = getCurrentPages();
87
+ if (props.isTabBarPage == true) {
88
+ pageShowHome.value = false;
89
+ pageShowBack.value = false;
90
+ } else if (pages.length == 1) {
91
+ pageShowHome.value = true;
92
+ pageShowBack.value = false;
93
+ } else {
94
+ pageShowHome.value = props.showHome;
95
+ pageShowBack.value = props.showBack;
96
+ }
97
+ };
98
+
99
+ </script>
100
+
101
+ <template>
102
+ <view class="page" :style="{
103
+ height: isTabBarPage ? '100%' : pageHeight,
104
+ background: pageBackgroundColor,
105
+ }">
106
+ <!--头部-->
107
+ <view v-if="hasHeader" class="header" :style="{
108
+ height: headerHeight + 'px',
109
+ background: headerBackgroundColor,
110
+ }">
111
+ <view class="status-bar" :style="{
112
+ height: statusBarHeight + 'px',
113
+ }">
114
+ </view>
115
+ <view class="header-slot">
116
+ <view v-if="uSlots.header">
117
+ <view style="display: flex; align-items: center">
118
+ <back-button :color="titleColor" :show-back="pageShowBack" :show-home="pageShowHome" />
119
+ <slot name="header" />
120
+ </view>
121
+ </view>
122
+
123
+ <view v-else>
124
+ {{ title }}
125
+ </view>
126
+ </view>
127
+ </view>
128
+
129
+ <!--内容-->
130
+ <scroll-view :style="{
131
+ background: bodyBackgroundColor,
132
+ }" class="body-scroll" :enhanced="false" :bounces="false" :scroll-y="true"
133
+ :refresher-enabled="refresh != null ? true : false" :refresher-triggered="triggered" :refresher-threshold="100"
134
+ :refresher-background="bodyBackgroundColor">
135
+ <view class="body-slot">
136
+ <!--页面主体内容是否可以滚动-->
137
+ <view class="back-button" v-if="!hasHeader">
138
+ <back-button :color="titleColor" :show-back="pageShowBack" :show-home="pageShowHome" />
139
+ </view>
140
+
141
+ <slot name="body" />
142
+ </view>
143
+ </scroll-view>
144
+
145
+ <!--底部-->
146
+ <view class="footer" v-if="uSlots.footer" :style="{
147
+ background: footerBackgroundColor,
148
+ }">
149
+ <slot name="footer"></slot>
150
+ <view :style="{ height: footer_safe_distance + 'rpx' }" />
151
+ </view>
152
+
153
+ <p-page-loading :visible="pageLoading"> </p-page-loading>
154
+
155
+ <view class="pendant" v-if="uSlots.pendant">
156
+ <slot name="pendant"> </slot>
157
+ </view>
158
+ </view>
159
+ </template>
160
+
161
+ <style scoped lang="scss">
162
+ .page {
163
+ width: 750rpx;
164
+ box-sizing: border-box;
165
+ display: flex;
166
+ flex-direction: column;
167
+ overflow: hidden;
168
+
169
+ .header {
170
+ width: 750rpx;
171
+ // border: 1px solid black;
172
+
173
+ .header-slot {
174
+ height: 44px;
175
+ display: flex;
176
+ align-items: center;
177
+ }
178
+ }
179
+
180
+ .back-button {
181
+ position: fixed;
182
+ top: 100rpx;
183
+ z-index: 10;
184
+ }
185
+
186
+ .body-scroll {
187
+ flex: 1;
188
+ min-width: 0;
189
+ min-height: 0;
190
+
191
+ .body-slot {
192
+ height: 100%;
193
+ position: relative;
194
+ }
195
+ }
196
+
197
+ .footer {
198
+ width: 750rpx;
199
+ }
200
+
201
+ .popup {
202
+ height: 0;
203
+ }
204
+
205
+ .pendant {
206
+ position: fixed;
207
+ height: 80rpx;
208
+ width: 80rpx;
209
+ z-index: 9999;
210
+ }
211
+ }
212
+ </style>
@@ -0,0 +1,29 @@
1
+ <script setup lang="ts">
2
+ import { ref, reactive, onMounted, useSlots } from 'vue';
3
+ const uSlots = useSlots();
4
+
5
+ const props = withDefaults(
6
+ defineProps<{
7
+ visible: boolean;
8
+ }>(),
9
+ {
10
+ visible: false,
11
+ }
12
+ );
13
+ </script>
14
+
15
+ <template>
16
+ <view v-if="visible" class="p-page-loading">
17
+ <slot name="custom" v-if="uSlots.custom"></slot>
18
+ <view v-else class="login-card">加载中</view>
19
+ </view>
20
+ </template>
21
+
22
+ <style lang="scss">
23
+ .p-page-loading {
24
+ inset: 0;
25
+ position: absolute;
26
+ background-color: #fff;
27
+ z-index: 9999999999;
28
+ }
29
+ </style>
@@ -0,0 +1,30 @@
1
+ import { ref } from "vue";
2
+
3
+ const visible = ref(false);
4
+ let resolver: ((value: any) => void) | null = null;
5
+ const urls = ref<string[]>([])
6
+ const current = ref(0)
7
+
8
+ const open = async (pics: string[], currentIndex: number) => {
9
+ urls.value = pics
10
+ current.value = currentIndex
11
+ visible.value = true;
12
+ return new Promise((resolve) => {
13
+ resolver = resolve;
14
+ });
15
+ };
16
+
17
+ // 取消
18
+ const cancel = () => {
19
+ visible.value = false;
20
+ resolver && resolver(false);
21
+ resolver = null;
22
+ };
23
+
24
+ export const RegisterPPreviewImage = {
25
+ urls,
26
+ current,
27
+ visible,
28
+ open,
29
+ cancel
30
+ }
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <view class="previewImage" v-if="visible" @click="close">
3
+ <view class="page" v-if="urls.length > 0">
4
+ <text class="text">{{ current + 1 }} / {{ urls.length }}</text>
5
+ </view>
6
+ <swiper class="swiper" :current="current" @change="swiperChange" @touchstart="handleTouchStart"
7
+ @touchend="handleTouchEnd">
8
+ <swiper-item v-for="(item, index) in urls" :key="index">
9
+ <movable-area class="movable-area" scale-area>
10
+ <movable-view class="movable-view" direction="all" :inertia="true" damping="100" scale="true"
11
+ scale-min="1" scale-max="4" :scale-value="scale">
12
+ <scroll-view scroll-y="true" class="uni-scroll-view">
13
+ <view class="scroll-view">
14
+ <image :key="index" class="image" :src="item" mode="widthFix"
15
+ @longpress="onLongpress(item)" />
16
+ </view>
17
+ </scroll-view>
18
+ </movable-view>
19
+ </movable-area>
20
+ </swiper-item>
21
+ </swiper>
22
+ </view>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import { ref,withDefaults } from "vue";
27
+
28
+ const props = withDefaults(defineProps<{
29
+ urls:string[],
30
+ current:number,
31
+ visible:boolean
32
+ }>(),{
33
+ visible:false,
34
+ current:0
35
+ })
36
+
37
+
38
+ const emits = defineEmits(['update:visible','update:current'])
39
+
40
+
41
+ const scale = ref(1)
42
+ const isZooming = ref(false)
43
+
44
+
45
+
46
+ const close = () => {
47
+ emits('update:visible',false)
48
+ }
49
+
50
+
51
+ //图片改变
52
+ const swiperChange = (e) => {
53
+ emits('update:current',e.detail.current)
54
+ }
55
+
56
+ const handleTouchStart = () => {
57
+ isZooming.value = true;
58
+ }
59
+ const handleTouchEnd = () => {
60
+ isZooming.value = false;
61
+ }
62
+
63
+
64
+ </script>
65
+
66
+ <style lang="scss" scoped>
67
+ .previewImage {
68
+ z-index: 9999;
69
+ position: fixed;
70
+ top: 0;
71
+ left: 0;
72
+ width: 100%;
73
+ height: 100%;
74
+ background-color: #000000;
75
+
76
+ .swiper {
77
+ width: 100%;
78
+ height: 100vh;
79
+
80
+ swiper-item {
81
+ .movable-area {
82
+ height: 100%;
83
+ width: 100%;
84
+
85
+ .movable-view {
86
+ width: 100%;
87
+ min-height: 100%;
88
+
89
+ .uni-scroll-view {
90
+ height: 100vh;
91
+ }
92
+
93
+ .scroll-view {
94
+ display: flex;
95
+ align-items: center;
96
+ justify-content: center;
97
+ min-height: 100vh;
98
+
99
+ .image {
100
+ width: 100%;
101
+ height: auto;
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+
109
+ .page {
110
+ position: absolute;
111
+ z-index: 9999;
112
+ width: 100%;
113
+ top: 60rpx;
114
+ text-align: center;
115
+
116
+ .text {
117
+ color: #fff;
118
+ font-size: 32rpx;
119
+ background-color: rgba(0, 0, 0, 0.5);
120
+ padding: 3rpx 16rpx;
121
+ border-radius: 20rpx;
122
+ user-select: none;
123
+ }
124
+ }
125
+ }
126
+ </style>
package/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { RegisterPPreviewImage } from "./components/p-preview-image/p-preview-image-register"
2
+
3
+ export { RegisterPPreviewImage }
4
+
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "p-pc-ui",
3
- "version": "1.2.2",
3
+ "version": "1.2.5",
4
4
  "type": "module",
5
- "module": "dist/index.ts",
6
- "main": "dist/index.ts",
5
+ "module": "index.ts",
6
+ "main": "index.ts",
7
7
  "files": [
8
- "dist"
8
+ "components",
9
+ "utils",
10
+ "index.ts"
9
11
  ],
10
12
  "peerDependencies": {
11
13
  "vue": "^3.0.0"
@@ -18,17 +20,10 @@
18
20
  "license": "ISC",
19
21
  "description": "",
20
22
  "dependencies": {
21
- "@ant-design/icons-vue": "^7.0.1",
22
- "ant-design-vue": "4.2.6",
23
- "dayjs": "^1.11.13",
24
- "v-viewer": "^3.0.21",
25
- "vue": "3.5.13",
26
- "@wangeditor/editor": "^5.1.23",
27
- "@wangeditor/editor-for-vue": "next"
23
+ "vue": "3.5.13"
28
24
  },
29
25
  "devDependencies": {
30
- "typescript": "5.8.3"
31
- },
32
- "_from": "p-pc-ui@1.1.7",
33
- "_resolved": "https://registry.npmmirror.com/p-pc-ui/-/p-pc-ui-1.1.7.tgz"
34
- }
26
+ "typescript": "5.8.3",
27
+ "@dcloudio/types": "^3.4.8"
28
+ }
29
+ }
@@ -94,9 +94,9 @@ export const set = (obj: object, path: string | string[], value: any) => {
94
94
  }
95
95
 
96
96
 
97
- export const formatTime = (input:any) => {
97
+ export const formatTime = (input: any) => {
98
98
  const date = new Date(input)
99
- const pad = (n:any) => n.toString().padStart(2, '0')
99
+ const pad = (n: any) => n.toString().padStart(2, '0')
100
100
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ` +
101
101
  `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
102
102
  }
@@ -108,11 +108,47 @@ export const formatTime = (input:any) => {
108
108
  export const pickBy = (object, predicate) => {
109
109
  const result = {}
110
110
  for (const key in object) {
111
- if (Object.prototype.hasOwnProperty.call(object, key)) {
112
- if (predicate(object[key], key)) {
113
- result[key] = object[key]
114
- }
111
+ if (Object.prototype.hasOwnProperty.call(object, key)) {
112
+ if (predicate(object[key], key)) {
113
+ result[key] = object[key]
115
114
  }
115
+ }
116
116
  }
117
117
  return result
118
- }
118
+ }
119
+
120
+
121
+
122
+ const paramsToString = (params) => {
123
+ let query: string[] = []
124
+ for (const key in params) {
125
+ query.push(`${key}=${params[key]}`)
126
+ }
127
+
128
+ let url = ''
129
+
130
+ if (query.length > 0) {
131
+ url += `?${query.join('&')}`
132
+ }
133
+
134
+ return url
135
+ }
136
+
137
+
138
+ export const navTo = (url, params = {}) => {
139
+ uni.navigateTo({ url: url + paramsToString(params) })
140
+ }
141
+
142
+
143
+ export const dirTo = (url, params = {}) => {
144
+ uni.redirectTo({ url: url + paramsToString(params) })
145
+ }
146
+
147
+ export const switchTo = (url) => {
148
+ uni.switchTab({ url })
149
+ }
150
+
151
+ export const backTo = (delta = 1) => {
152
+ uni.navigateBack({ delta })
153
+ }
154
+
package/utils/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import * as dataUtils from './dataUtils'
2
+
3
+ export {dataUtils}
@@ -1,118 +0,0 @@
1
- type FieldRule = { msg?: string, required?: boolean, min?: number, max?: number, decimal?: number }
2
-
3
- interface Base {
4
- key: string,
5
- label: string,
6
- default?: any,
7
- placeholder?: string,
8
- fieldType?: 'string' | 'number' | 'array' | 'date',
9
- fieldRules?: FieldRule[];
10
- visibleHook?: Function,
11
- tooltip?: string,
12
- hideLabel?: boolean
13
- colon?: boolean,
14
- labelSpan?: number,
15
- valueSpan?: number,
16
- labelAlign?: 'left' | 'right'
17
- }
18
-
19
-
20
- export interface Input extends Base {
21
- type: 'input',
22
- prefix?: any,
23
- suffix?: any
24
- }
25
-
26
- export interface InputNumber extends Base {
27
- type: 'number',
28
- prefix?: any,
29
- suffix?: any
30
- }
31
-
32
- export interface InputPassword extends Base {
33
- type: 'password',
34
- prefix?: any,
35
- }
36
-
37
- export interface InputCode extends Base {
38
- type: 'code',
39
- interval: number,
40
- codeName: string,
41
- sendNoticeFunc: Function
42
- activityFunc?: Function
43
- prefix?: any,
44
- suffix?: any,
45
- sendStatus?: 'waitSend' | 'sending' | 'end',
46
- }
47
-
48
-
49
-
50
- type LoadOptionsData = () => Promise<{ label: string, value: any }[]>
51
-
52
-
53
- interface SelectBase extends Base {
54
- type: 'select' | 'treeSelect' | 'radio',
55
- fieldNames?: {
56
- label?: string;
57
- value?: string;
58
- };
59
- isMultiple?: boolean
60
- }
61
-
62
- type GetOptionList =
63
- | { optionList: any[]; mapPath?: never; loadDataFunc?: LoadOptionsData }
64
- | { optionList?: any[]; mapPath: string[], loadDataFunc?: LoadOptionsData }
65
- | { optionList?: any[]; mapPath?: string[], loadDataFunc: LoadOptionsData }
66
-
67
- export type Select = SelectBase & GetOptionList;
68
-
69
-
70
- interface UploadBase extends Base {
71
- uploadType: 'pic' | 'file',
72
- maxCount?: number,
73
- }
74
-
75
- export interface UploadOss extends UploadBase {
76
- type: 'uploadOss',
77
- getOssToken: ({file_name}) => Promise<any>,
78
- baseOssUrl: string,
79
- }
80
-
81
-
82
- export interface Upload extends UploadBase {
83
- type: 'upload',
84
- }
85
-
86
- export interface Textarea extends Base {
87
- type: 'textarea',
88
- }
89
-
90
- export interface DatePicker extends Base {
91
- type: 'datePicker',
92
- }
93
-
94
-
95
- export interface Component extends Base {
96
- type: 'component',
97
- component: any
98
- }
99
-
100
- export interface Editor extends Base {
101
- type: 'editor',
102
- getOssToken: ({ file_name: string }) => Promise<any>,
103
- baseOssUrl?: string,
104
- }
105
-
106
-
107
- export type FormDataItem =
108
- | Input
109
- | InputNumber
110
- | InputPassword
111
- | InputCode
112
- | Select
113
- | Upload
114
- | UploadOss
115
- | Textarea
116
- | DatePicker
117
- | Component
118
- | Editor