business_tms_program 0.0.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 (136) hide show
  1. package/.editorconfig +12 -0
  2. package/.eslintrc-auto-import.json +113 -0
  3. package/.eslintrc.js +121 -0
  4. package/.prettierrc.js +9 -0
  5. package/.stylelintignore +4 -0
  6. package/README.md +43 -0
  7. package/components.d.ts +23 -0
  8. package/index.html +20 -0
  9. package/package.json +70 -0
  10. package/shims-uni.d.ts +10 -0
  11. package/src/App.vue +81 -0
  12. package/src/api/afterSale.ts +184 -0
  13. package/src/api/context.ts +26 -0
  14. package/src/api/device.ts +134 -0
  15. package/src/api/index.ts +80 -0
  16. package/src/api/installtion.ts +155 -0
  17. package/src/api/model/index.ts +15 -0
  18. package/src/api/model/userModel.ts +62 -0
  19. package/src/api/order.ts +49 -0
  20. package/src/api/system.ts +19 -0
  21. package/src/api/user.ts +171 -0
  22. package/src/auto-imports.d.ts +108 -0
  23. package/src/components/ConfirmDialog.vue +101 -0
  24. package/src/components/DaySelect.vue +212 -0
  25. package/src/components/Drawer.vue +104 -0
  26. package/src/components/DrawerSelect.vue +105 -0
  27. package/src/components/DropMenu.vue +144 -0
  28. package/src/components/Empty.vue +49 -0
  29. package/src/components/Loading.vue +41 -0
  30. package/src/components/RippleBtn.vue +159 -0
  31. package/src/components/SinglePick.vue +120 -0
  32. package/src/components/Skeleton.vue +43 -0
  33. package/src/components/Timeline.vue +85 -0
  34. package/src/components/Upload.vue +217 -0
  35. package/src/config/app.ts +32 -0
  36. package/src/config/env.ts +29 -0
  37. package/src/dict/afterSale.ts +161 -0
  38. package/src/dict/device.ts +29 -0
  39. package/src/dict/installtion.ts +141 -0
  40. package/src/dict/systems.ts +4 -0
  41. package/src/env.d.ts +8 -0
  42. package/src/hooks/useForm.ts +222 -0
  43. package/src/hooks/useUpload.ts +80 -0
  44. package/src/main.ts +8 -0
  45. package/src/manifest.json +39 -0
  46. package/src/pages/acceptance/DeviceInfo.vue +132 -0
  47. package/src/pages/acceptance/list.vue +276 -0
  48. package/src/pages/afterSale/DeviceInfo.vue +128 -0
  49. package/src/pages/afterSale/Step.vue +0 -0
  50. package/src/pages/afterSale/faultReport.vue +552 -0
  51. package/src/pages/afterSale/orderDetail.vue +327 -0
  52. package/src/pages/afterSale/orderFinish.vue +517 -0
  53. package/src/pages/afterSale/orderList.vue +305 -0
  54. package/src/pages/afterSale/returnVisit.vue +288 -0
  55. package/src/pages/afterSale/searchDeviceList.vue +148 -0
  56. package/src/pages/device/Search.vue +201 -0
  57. package/src/pages/device/acceptance.vue +270 -0
  58. package/src/pages/device/detail.vue +165 -0
  59. package/src/pages/device/index.vue +322 -0
  60. package/src/pages/device/info.vue +140 -0
  61. package/src/pages/device/list.vue +219 -0
  62. package/src/pages/device/materialTowerCode.vue +589 -0
  63. package/src/pages/device/searchList.vue +224 -0
  64. package/src/pages/installtion/Record.vue +145 -0
  65. package/src/pages/installtion/StatusTimeline.vue +85 -0
  66. package/src/pages/installtion/addAcceptance.vue +409 -0
  67. package/src/pages/installtion/addRecord.vue +338 -0
  68. package/src/pages/installtion/orderDetail.vue +220 -0
  69. package/src/pages/installtion/orderList.vue +100 -0
  70. package/src/pages/user/component/PersonAgree.vue +226 -0
  71. package/src/pages/user/component/PrivayAgree.vue +221 -0
  72. package/src/pages/user/component/SliderCode.vue +173 -0
  73. package/src/pages/user/forgetPassword.vue +249 -0
  74. package/src/pages/user/index.vue +139 -0
  75. package/src/pages/user/login.vue +342 -0
  76. package/src/pages/user/register.vue +348 -0
  77. package/src/pages/user/repassword.vue +329 -0
  78. package/src/pages/user/utils/mcaptcha.js +75 -0
  79. package/src/pages/user/utils/verifyCode.ts +41 -0
  80. package/src/pages/workspace/index.vue +225 -0
  81. package/src/pages.json +203 -0
  82. package/src/shime-uni.d.ts +6 -0
  83. package/src/static/icon/system/breeder_icon.png +0 -0
  84. package/src/static/icon/system/check.png +0 -0
  85. package/src/static/icon/system/factory_icon.png +0 -0
  86. package/src/static/icon/system/plus.png +0 -0
  87. package/src/static/icon/system/right.png +0 -0
  88. package/src/static/icon/system/unCheck.png +0 -0
  89. package/src/static/icon/tab/search.png +0 -0
  90. package/src/static/icon/tab/user.png +0 -0
  91. package/src/static/icon/tab/user_active.png +0 -0
  92. package/src/static/icon/tab/workspace.png +0 -0
  93. package/src/static/icon/tab/workspace_active.png +0 -0
  94. package/src/static/img/active_dot.png +0 -0
  95. package/src/static/img/afterSale_icon.png +0 -0
  96. package/src/static/img/check.png +0 -0
  97. package/src/static/img/close.png +0 -0
  98. package/src/static/img/confirm.png +0 -0
  99. package/src/static/img/empty.png +0 -0
  100. package/src/static/img/equipment_icon.png +0 -0
  101. package/src/static/img/fault_icon.png +0 -0
  102. package/src/static/img/install_icon.png +0 -0
  103. package/src/static/img/login_bg2.png +0 -0
  104. package/src/static/img/movable_right.png +0 -0
  105. package/src/static/img/navigation.png +0 -0
  106. package/src/static/img/psw_off.png +0 -0
  107. package/src/static/img/psw_on.png +0 -0
  108. package/src/static/img/scan.png +0 -0
  109. package/src/static/img/scan_icon.png +0 -0
  110. package/src/static/img/search.png +0 -0
  111. package/src/static/img/turn_right.png +0 -0
  112. package/src/static/img/unActive_dot.png +0 -0
  113. package/src/static/img/verifyBg.png +0 -0
  114. package/src/stores/index.ts +11 -0
  115. package/src/stores/modules/customer.ts +146 -0
  116. package/src/stores/modules/installtion.ts +30 -0
  117. package/src/stores/modules/system.ts +56 -0
  118. package/src/stores/modules/user.ts +133 -0
  119. package/src/stores/types.ts +16 -0
  120. package/src/stores/utils.ts +6 -0
  121. package/src/styles/index.less +63 -0
  122. package/src/types/chengyiApi.d.ts +36 -0
  123. package/src/types/index.d.ts +95 -0
  124. package/src/utils/address.ts +17 -0
  125. package/src/utils/cipher.ts +61 -0
  126. package/src/utils/form.ts +155 -0
  127. package/src/utils/httpEnum.ts +31 -0
  128. package/src/utils/image.ts +21 -0
  129. package/src/utils/index.ts +111 -0
  130. package/src/utils/request.ts +139 -0
  131. package/src/utils/requestCancelHandle.ts +67 -0
  132. package/stylelint.config.js +87 -0
  133. package/tsconfig.docs.json +11 -0
  134. package/tsconfig.json +30 -0
  135. package/typedoc.json +6 -0
  136. package/vite.config.ts +55 -0
@@ -0,0 +1,342 @@
1
+ <script setup lang="ts">
2
+ import { useForm } from '@/hooks/useForm';
3
+ import { type ValidationRules, validatePsw } from '@/utils/form';
4
+ import { throttle } from 'lodash-es';
5
+ import { useUserStore } from '@/stores/modules/user';
6
+ import RippleBtn from '@/components/RippleBtn.vue';
7
+ import PrivayAgree from './component/PrivayAgree.vue';
8
+ import PersonAgree from './component/PersonAgree.vue';
9
+ import Drawer from '@/components/Drawer.vue';
10
+ import loginBg from '@/static/img/login_bg2.png'
11
+
12
+ defineOptions({
13
+ name: "login"
14
+ });
15
+ type FormDataType = {
16
+ name: string;
17
+ password: string;
18
+ }
19
+ // 定义校验规则
20
+ const validationRules: ValidationRules<FormDataType> = {
21
+ name: {
22
+ required: true,
23
+ message: '请输入手机号码',
24
+ validatFunc: (value: string): any => {
25
+ return new Promise((resolve, reject) => {
26
+ if (!value) {
27
+ reject('请输入手机号码')
28
+ } else if (!/^1[3-9]\d{9}$/.test(value)) {
29
+ reject('请输入正确的手机号码')
30
+ } else {
31
+ resolve(true)
32
+ }
33
+ })
34
+ }
35
+ },
36
+ password: { required: true, validatFunc: validatePsw, message: '请输入密码' },
37
+ }
38
+
39
+ const initialData = {
40
+ name: '',
41
+ password: '',
42
+ files: []
43
+ } as FormDataType;
44
+
45
+ const useStore = useUserStore();
46
+ const focusState = reactive({
47
+ name: false,
48
+ password: false,
49
+ })
50
+ const { formData, errState, setFormItem, validateForm } = useForm<FormDataType>(
51
+ initialData,
52
+ validationRules,
53
+ true,
54
+ )
55
+ const headerHeight = ref(0);
56
+ const hasAgree = ref(false);
57
+ const showDrawer = ref(false);
58
+ const agreementType = ref('privacy');
59
+ const showPassword = ref(false);
60
+ const changeValue = (key: keyof FormDataType, detail: any) => {
61
+ setFormItem(key, detail.value);
62
+ }
63
+
64
+ const submitForm = throttle(async() => {
65
+ const validate = await validateForm()
66
+ if (!validate) {
67
+ return
68
+ }
69
+ if (!hasAgree.value) {
70
+ uni.showToast({
71
+ title: '请先阅读协议',
72
+ icon: 'none'
73
+ })
74
+ return;
75
+ }
76
+ useStore.toLogin(formData)
77
+ }, 1000)
78
+
79
+ onLoad(() => {
80
+ const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
81
+ headerHeight.value = (menuButtonInfo.height + menuButtonInfo.top + 8) * 2;
82
+ })
83
+ const placeholderStyle = `color: rgba(0, 0, 0, 0.4)`;
84
+ const togglePasswordVisibility = () => {
85
+ showPassword.value = !showPassword.value;
86
+ }
87
+ const toRegiter = () => {
88
+ uni.redirectTo({ url: '/pages/user/register' })
89
+ }
90
+ const toResetPwd = () => {
91
+ uni.redirectTo({ url: '/pages/user/rePassword' })
92
+ }
93
+ const checkboxChange = (e: any) => {
94
+ hasAgree.value = e.detail.value.includes('aggrement');
95
+ }
96
+ const toAgree = () => {
97
+ showDrawer.value = false;
98
+ hasAgree.value = true;
99
+ }
100
+ const showAgreement = (type:string) => {
101
+ showDrawer.value = true;
102
+ agreementType.value = type;
103
+ }
104
+ </script>
105
+
106
+ <template>
107
+ <image class="bgImg" :src="loginBg" mode="aspectFill" />
108
+ <view class="page-content">
109
+ <view class="header" :style="{height: `${headerHeight}rpx`}"><view class="title">诚一工单</view></view>
110
+ <canvas style="width:220rpx;height:86rpx;" canvas-id="canvas"></canvas>
111
+ <form class="form-content">
112
+ <view class="systemName">手机登录页</view>
113
+ <view class="uni-form-item uni-column">
114
+ <input class="uni-input"
115
+ :value="formData.name"
116
+ :class="focusState.name ? 'focus' : ''"
117
+ :placeholder-style="placeholderStyle" type="text" placeholder="请输入手机号"
118
+ @input="(e: any) => changeValue('name', e.detail)"
119
+ @focus="focusState.name = true"
120
+ @blur="focusState.name = false"
121
+ />
122
+ </view>
123
+ <view class="err-text" v-if="errState.name">{{errState.name}}</view>
124
+ <view class="uni-form-item uni-column">
125
+ <input class="uni-input"
126
+ :value="formData.password"
127
+ :class="focusState.password ? 'focus' : ''"
128
+ :placeholder-style="placeholderStyle"
129
+ :password="!showPassword" placeholder="请输入密码"
130
+ @input="(e: any) => changeValue('password', e.detail)"
131
+ @focus="focusState.password = true"
132
+ @blur="focusState.password = false"
133
+ />
134
+ <image class="uni-icon" :src="
135
+ !showPassword
136
+ ? '/static/img/psw_off.png'
137
+ : '/static/img/psw_on.png'
138
+ " @click="togglePasswordVisibility"></image>
139
+ </view>
140
+ <view class="err-text" v-if="errState.password">{{errState.password}}</view>
141
+ </form>
142
+ <RippleBtn @click="submitForm" :customStyle="'padding-bottom: 10rpx'">
143
+ <view class="submit-btn">登 录</view>
144
+ </RippleBtn>
145
+ <view class="otherControl"><view @click="toRegiter">注册</view><view @click="toResetPwd">忘记密码</view></view>
146
+ <view class="aggrement">
147
+ <checkbox-group name="aggrement" @change="checkboxChange">
148
+ <label class="checkbox">
149
+ <checkbox value="aggrement" :checked="hasAgree" style="transform:scale(0.6)" />
150
+ <view class="flex">我已阅读</view>
151
+ </label>
152
+ </checkbox-group>
153
+ <view class="aggrement-text">
154
+ <view class="text" @click="showAgreement('person')">《服务协议》</view>与
155
+ <view class="text" @click="showAgreement('privacy')">《隐私政策》</view><view>并理解相关条款内容</view>
156
+ </view>
157
+ </view>
158
+ </view>
159
+ <drawer v-model="showDrawer" :height="70">
160
+ <view class="agree-box">
161
+ <scroll-view scroll-y class="scroll-box">
162
+ <view class="agree-content">
163
+ <PrivayAgree v-if="agreementType === 'privacy'"/>
164
+ <PersonAgree v-else />
165
+ <view class="agree-btn" @click="toAgree">同意</view>
166
+ </view>
167
+ </scroll-view>
168
+ </view>
169
+ </drawer>
170
+ </template>
171
+
172
+ <style scoped>
173
+ .bgImg{
174
+ position: relative;
175
+ width: 100%;
176
+ height: 1624rpx;
177
+ z-index: 1;
178
+ }
179
+ .page-content {
180
+ position: absolute;
181
+ top: 0;
182
+ left: 0;
183
+ right: 0;
184
+ bottom: 0;
185
+ z-index: 2;
186
+ overflow-y: auto;
187
+ display: flex;
188
+ flex-direction: column;
189
+ .header{
190
+ width: 100%;
191
+ height: 190rpx;
192
+ background: rgba(255,255,255,0.05);
193
+ backdrop-filter: blur(32rpx);
194
+ border-bottom: 1rpx solid rgba(0,0,0,0.05);
195
+ .title{
196
+ position: absolute;
197
+ bottom: 16rpx;
198
+ width: 100%;
199
+ font-weight: bold;
200
+ font-size: 40rpx;
201
+ line-height: 58rpx;
202
+ text-align: center;
203
+ }
204
+ }
205
+ .form-content{
206
+ margin-bottom: 96rpx;
207
+ padding: 0 48rpx;
208
+ }
209
+ .systemName{
210
+ margin-top: 556rpx;
211
+ margin-bottom: 22rpx;
212
+ font-family: Source Han Sans SC, Source Han Sans SC;
213
+ font-weight: bold;
214
+ font-size: 48rpx;
215
+ color: #000000;
216
+ line-height: 70rpx;
217
+ }
218
+ .uni-form-item {
219
+ display: flex;
220
+ justify-content: space-between;
221
+ width: 100%;
222
+ margin-top: 40rpx;
223
+ padding: 0 16rpx;
224
+ position: relative;
225
+ .uni-input {
226
+ flex: 1;
227
+ padding: 12rpx 0;
228
+ border-bottom: 1rpx solid rgba(0,0,0,0.05);
229
+ font-family: Source Han Sans SC, Source Han Sans SC;
230
+ font-weight: 400;
231
+ font-size: 32rpx;
232
+ color: black;
233
+ line-height: 48rpx;
234
+ text-align: left;
235
+ font-style: normal;
236
+ /* 防止字体变化 */
237
+ min-height: 48rpx;
238
+ &.focus {
239
+ border-bottom-color: #1D6FE9 ; /* 聚焦时改变下划线颜色 */
240
+ outline: none; /* 移除默认的聚焦轮廓 */
241
+ line-height: 48rpx !important; /* 强制保持行高 */
242
+ font-size: 32rpx !important; /* 强制保持字体大小 */
243
+ }
244
+ }
245
+ .eyeBox{
246
+ position: absolute;
247
+ right: 16rpx;
248
+ top: 12rpx;
249
+ width: 120rpx;
250
+ height: 48rpx;
251
+ }
252
+ .uni-icon{
253
+ position: absolute;
254
+ right: 32rpx;
255
+ top: 16rpx;
256
+ width: 32rpx;
257
+ height: 32rpx;
258
+ z-index: 5;
259
+ }
260
+ }
261
+ .err-text{
262
+ margin-top: 8rpx;
263
+ padding-left: 16rpx;
264
+ font-size: 24rpx;
265
+ color: rgb(245, 140, 140);
266
+ }
267
+ .submit-btn{
268
+ margin-left: 32rpx;
269
+ padding: 24rpx 300rpx 26rpx 298rpx;
270
+ line-height: 58rpx;
271
+ font-family: Source Han Sans SC, Source Han Sans SC;
272
+ font-weight: 400;
273
+ font-size: 40rpx;
274
+ color: rgba(255, 255, 255, 0.9);
275
+ background: linear-gradient( 270deg, #1D9DE9 0%, #1D6FE9 100%);
276
+ box-shadow: 0px 16rpx 16rpx 2rpx rgba(29,157,233,0.1);
277
+ border-radius: 52rpx;
278
+ }
279
+ .otherControl{
280
+ display: flex;
281
+ justify-content: space-between;
282
+ margin-top: 28rpx;
283
+ margin-bottom: 244rpx;
284
+ padding: 0 64rpx;
285
+ font-size: 28rpx;
286
+ color: rgba(0,0,0,0.4);
287
+ line-height: 40rpx;
288
+ }
289
+ .agreement{
290
+ font-size: 24rpx;
291
+ color: rgba(0,0,0,0.2);
292
+ line-height: 34rpx;
293
+ text-align: center;
294
+ }
295
+ }
296
+ .aggrement{
297
+ position: fixed;
298
+ bottom: 96rpx;
299
+ left: 32rpx;
300
+ overflow-y: auto;
301
+ display: flex;
302
+ align-items: center;
303
+ .checkbox{
304
+ display: flex;
305
+ align-items: center;
306
+ font-size: 24rpx;
307
+ color: rgba(0,0,0,0.6);
308
+ line-height: 32rpx;
309
+ }
310
+ .aggrement-text{
311
+ display: flex;
312
+ font-size: 24rpx;
313
+ color: rgba(0,0,0,0.6);
314
+ line-height: 32rpx;
315
+ }
316
+ .text {
317
+ color: #1D6FE9;
318
+ }
319
+ }
320
+ .agree-box{
321
+ padding: 80rpx 32rpx 24rpx 32rpx;
322
+ .scroll-box{
323
+ height: calc(70vh - 154rpx);
324
+ }
325
+ .agree-content{
326
+ padding-bottom: 32rpx;
327
+ }
328
+ .agree-btn{
329
+ text-align: center;
330
+ width: 560rpx;
331
+ margin: 24rpx auto 22rpx auto;
332
+ padding: 10rpx 0 12rpx 0;
333
+ line-height: 48rpx;
334
+ font-family: Source Han Sans SC, Source Han Sans SC;
335
+ font-weight: 400;
336
+ font-size: 27rpx;
337
+ color: rgba(255, 255, 255, 0.9);
338
+ background: linear-gradient( 270deg, #1D6FE9 0%, #1D9DE9 100%);
339
+ box-shadow: 0rpx 6rpx 12rpx 2rpx rgba(0,191,41,0.16);
340
+ }
341
+ }
342
+ </style>
@@ -0,0 +1,348 @@
1
+ <script setup lang="ts">
2
+ import { useForm } from '@/hooks/useForm';
3
+ import { reactive } from 'vue';
4
+ import { type ValidationRules, validatePsw } from '@/utils/form';
5
+ import { useVerifyCode } from "./utils/verifyCode";
6
+ import { throttle } from 'lodash-es';
7
+ import RippleBtn from '@/components/RippleBtn.vue';
8
+ import { type registerParams, registerApi, getRegisterPswAuth } from '@/api/user';
9
+ import { sendRegisterCode } from '@/api/system';
10
+ import SliderCode from './component/SliderCode.vue';
11
+
12
+ defineOptions({
13
+ name: "register"
14
+ });
15
+
16
+ const initialData = {
17
+ "nickname": '',
18
+ "mobile": undefined,
19
+ "code": undefined,
20
+ "password": '',
21
+ "confirmPassword": ''
22
+ } as registerParams;
23
+ const validationRules: ValidationRules<Partial<registerParams>> = {
24
+ mobile: {
25
+ required: true,
26
+ validatFunc: (value: any): any => {
27
+ return new Promise((resolve, reject) => {
28
+ if (value === "") {
29
+ reject("请输入");
30
+ } else if (!/^1[3-9]\d{9}$/.test(value)) {
31
+ reject("手机号格式不正确");
32
+ } else {
33
+ state.isPhoneValidateCode = true;
34
+ resolve(true);
35
+ }
36
+ })
37
+ } // 添加手机号验证规则
38
+ },
39
+ code: { required: true, validatFunc: (value: any): any => {
40
+ return new Promise(async(resolve, reject) => {
41
+ if (value === "") {
42
+ state.isValidateCode = false;
43
+ reject("请输入验证码");
44
+ return
45
+ } if (!/^\d{6}$/.test(value)) {
46
+ state.isValidateCode = false;
47
+ reject("验证码格式不正确");
48
+ return
49
+ }
50
+ getRegisterPswAuth({ mobile: formData.mobile, code: value }).then(res => {
51
+ if (!res) {
52
+ state.isValidateCode = false;
53
+ reject("验证码验证失败");
54
+ } else {
55
+ resolve(true);
56
+ state.isValidateCode = true;
57
+ }
58
+ })
59
+ }
60
+ )}
61
+ },
62
+ nickname: { required: true, validatFunc: (value: string): any => {
63
+ return new Promise(async(resolve, reject) => {
64
+ if (!value) {
65
+ reject("请输入");
66
+ } else if (!/^[\u4e00-\u9fa5a-zA-Z0-9]{2,10}$/.test(value)) {
67
+ reject("2-10字,请勿使用特殊字符");
68
+ } else {
69
+ resolve(true);
70
+ }
71
+ }
72
+ );
73
+ }},
74
+ password: { required: true, message: '请输入', validatFunc: validatePsw },
75
+ confirmPassword: { required: true, validatFunc: (value: string): any => {
76
+ return new Promise(async(resolve, reject) => {
77
+ if (value !== formData.password) {
78
+ reject("两次密码不一致");
79
+ } else {
80
+ resolve(true);
81
+ }
82
+ }
83
+ );
84
+ }}
85
+ }
86
+ const focusState = reactive({
87
+ nickname: false,
88
+ mobile: false,
89
+ code: false,
90
+ password: false,
91
+ confirmPassword: false
92
+ })
93
+ const { text, end } = useVerifyCode();
94
+ const { formData, errState, setFormItem, validateForm,
95
+ validateOneField } = useForm<registerParams>(
96
+ initialData,
97
+ validationRules
98
+ )
99
+ const state = reactive({
100
+ showPassword: false,
101
+ isValidateCode: false,
102
+ isPhoneValidateCode: false,
103
+ isSliderValidate: false,
104
+ showCaptcha: false,
105
+ })
106
+ const changeValue = (key: keyof registerParams, detail: any) => {
107
+ if (key === 'code') {
108
+ validateOneField('code')
109
+ }
110
+ setFormItem(key, detail.value);
111
+ }
112
+
113
+ const submitForm = throttle(async() => {
114
+ const validateResult = await validateForm();
115
+ if (!validateResult) {
116
+ return;
117
+ }
118
+ const res = await registerApi(formData)
119
+ if (res) {
120
+ uni.showToast({ title: '注册成功,请联系管理员配置权限!', icon: 'success' })
121
+ }
122
+ }, 1000)
123
+ const togglePasswordVisibility = () => {
124
+ state.showPassword = !state.showPassword;
125
+ }
126
+ const clearIcon = (type: keyof registerParams) => {
127
+ setFormItem(type, '')
128
+ }
129
+ const getVerifyCode = async() => {
130
+ const validate = await validateOneField('mobile')
131
+ if (!validate) {
132
+ return
133
+ }
134
+ if (state.isSliderValidate) {
135
+ successVlidate()
136
+ return
137
+ }
138
+ state.showCaptcha = true;
139
+ }
140
+ const successVlidate = async() => {
141
+ state.isSliderValidate = true;
142
+ const res = await sendRegisterCode({ mobile: formData.mobile })
143
+ if (res) {
144
+ uni.showToast({ title: '验证码已发送', icon:'success' })
145
+ useVerifyCode().start()
146
+ }
147
+ }
148
+ const placeholderStyle = `color: rgba(0, 0, 0, 0.4)`;
149
+ onShow(() => {
150
+ end()
151
+ })
152
+ </script>
153
+
154
+ <template>
155
+ <view class="content">
156
+ <form class="form-content">
157
+ <view class="systemName">新用户注册</view>
158
+ <view class="uni-form-item uni-column">
159
+ <input class="uni-input"
160
+ :class="focusState.mobile ? 'focus' : ''"
161
+ :placeholder-style="placeholderStyle" type="text" placeholder="请输入手机号"
162
+ :value="formData['mobile']"
163
+ @input="(e: any) => changeValue('mobile', e.detail)"
164
+ @focus="focusState.mobile = true"
165
+ @blur="focusState.mobile = false"
166
+ />
167
+ <image class="uni-icon"
168
+ src="/static/img/close.png"
169
+ v-if="formData['mobile']"
170
+ @click="clearIcon('mobile')">
171
+ </image>
172
+ </view>
173
+ <view class="err-text" v-if="errState.mobile">{{errState.mobile}}</view>
174
+ <SliderCode v-model="state.showCaptcha" @successVlidate="successVlidate" />
175
+ <view class="uni-form-item uni-column">
176
+ <input class="uni-input"
177
+ :class="focusState.code ? 'focus' : ''"
178
+ :placeholder-style="placeholderStyle" placeholder="请输入验证码"
179
+ @input="(e: any) => changeValue('code', e.detail)"
180
+ @focus="focusState.code = true"
181
+ @blur="focusState.code = false"
182
+ />
183
+ <view class="getCode">
184
+ <view v-if="text.length > 0">{{`${text}s`}}</view>
185
+ <view v-else @click="getVerifyCode()">获取验证码</view>
186
+ <image class="confirm-icon"
187
+ v-if="state.isValidateCode"
188
+ src="/static/img/confirm.png"
189
+ ></image>
190
+ </view>
191
+ </view>
192
+ <view class="err-text" v-if="errState.code">{{errState.code}}</view>
193
+ <view class="uni-form-item uni-column">
194
+ <input class="uni-input"
195
+ :class="focusState.nickname ? 'focus' : ''"
196
+ :placeholder-style="placeholderStyle" placeholder="请输入姓名"
197
+ @input="(e: any) => changeValue('nickname', e.detail)"
198
+ @focus="focusState.nickname = true"
199
+ @blur="focusState.nickname = false"
200
+ />
201
+ </view>
202
+ <view class="err-text" v-if="errState.nickname">{{errState.nickname}}</view>
203
+ <view class="uni-form-item uni-column">
204
+ <input class="uni-input"
205
+ :class="focusState.password ? 'focus' : ''"
206
+ :placeholder-style="placeholderStyle" :password="!state.showPassword" placeholder="请输入密码"
207
+ @input="(e: any) => changeValue('password', e.detail)"
208
+ @focus="focusState.password = true"
209
+ @blur="focusState.password = false"
210
+ />
211
+ <image class="uni-icon" :src="
212
+ !state.showPassword
213
+ ? '/static/img/psw_off.png'
214
+ : '/static/img/psw_on.png'
215
+ " @click="togglePasswordVisibility"></image>
216
+ </view>
217
+ <view class="err-text" v-if="errState.password">{{errState.password}}</view>
218
+
219
+ <view class="uni-form-item uni-column">
220
+ <input class="uni-input"
221
+ :class="focusState.confirmPassword ? 'focus' : ''"
222
+ :placeholder-style="placeholderStyle" password placeholder="请确认密码"
223
+ @input="(e: any) => changeValue('confirmPassword', e.detail)"
224
+ @focus="focusState.confirmPassword = true"
225
+ @blur="focusState.confirmPassword = false"
226
+ />
227
+ </view>
228
+ <view class="err-text" v-if="errState.confirmPassword">{{errState.confirmPassword}}</view>
229
+ </form>
230
+ <RippleBtn @click="submitForm" :customStyle="'padding-bottom: 10rpx'">
231
+ <view class="submit-btn">提交入驻</view>
232
+ </RippleBtn>
233
+ </view>
234
+ </template>
235
+
236
+ <style scoped>
237
+ .content {
238
+ display: flex;
239
+ flex-direction: column;
240
+ background-color: #fff;
241
+ .form-content{
242
+ margin-bottom: 216rpx;
243
+ padding: 0 48rpx;
244
+ }
245
+ .systemName{
246
+ margin-top: 64rpx;
247
+ margin-bottom: 64rpx;
248
+ font-family: Source Han Sans SC, Source Han Sans SC;
249
+ font-weight: bold;
250
+ font-size: 48rpx;
251
+ color: #000000;
252
+ line-height: 70rpx;
253
+ }
254
+ .uni-form-item {
255
+ display: flex;
256
+ justify-content: space-between;
257
+ width: 100%;
258
+ margin-top: 40rpx;
259
+ padding: 0 16rpx;
260
+ position: relative;
261
+ .uni-input {
262
+ flex: 1;
263
+ padding: 12rpx 0;
264
+ border-bottom: 1rpx solid rgba(0,0,0,0.05);
265
+ font-family: Source Han Sans SC, Source Han Sans SC;
266
+ font-weight: bold;
267
+ font-size: 32rpx;
268
+ color: black;
269
+ line-height: 48rpx;
270
+ text-align: left;
271
+ font-style: normal;
272
+ /* 防止字体变化 */
273
+ min-height: 48rpx;
274
+ &.focus {
275
+ border-bottom-color: #1D6FE9 ; /* 聚焦时改变下划线颜色 */
276
+ outline: none; /* 移除默认的聚焦轮廓 */
277
+ line-height: 48rpx !important; /* 强制保持行高 */
278
+ font-size: 32rpx !important; /* 强制保持字体大小 */
279
+ }
280
+ }
281
+ .eyeBox{
282
+ position: absolute;
283
+ right: 16rpx;
284
+ top: 12rpx;
285
+ width: 120rpx;
286
+ height: 48rpx;
287
+ }
288
+ .uni-icon{
289
+ position: absolute;
290
+ right: 32rpx;
291
+ bottom: 16rpx;
292
+ width: 32rpx;
293
+ height: 32rpx;
294
+ z-index: 5;
295
+ }
296
+ .getCode{
297
+ position: absolute;
298
+ right: 32rpx;
299
+ bottom: 18rpx;
300
+ font-size: 28rpx;
301
+ color: #1D6FE9;
302
+ line-height: 40rpx;
303
+ z-index: 5;
304
+ display: flex;
305
+ align-items: center;
306
+ .confirm-icon{
307
+ width: 36rpx;
308
+ height: 36rpx;
309
+ margin-left: 16rpx;
310
+ }
311
+ }
312
+ }
313
+ .err-text{
314
+ margin-top: 8rpx;
315
+ padding-left: 16rpx;
316
+ font-size: 24rpx;
317
+ color: rgb(250, 100, 100);
318
+ }
319
+ .submit-btn{
320
+ margin-left: 32rpx;
321
+ padding: 24rpx 262rpx 26rpx 262rpx;
322
+ line-height: 58rpx;
323
+ font-family: Source Han Sans SC, Source Han Sans SC;
324
+ font-weight: 400;
325
+ font-size: 40rpx;
326
+ color: rgba(255, 255, 255, 0.9);
327
+ background: linear-gradient( 270deg, #1D9DE9 0%, #1D6FE9 100%);
328
+ box-shadow: 0px 16rpx 16rpx 2rpx rgba(29,157,233,0.1);
329
+ border-radius: 52rpx;
330
+ }
331
+ .otherControl{
332
+ display: flex;
333
+ justify-content: space-between;
334
+ margin-top: 28rpx;
335
+ margin-bottom: 244rpx;
336
+ padding: 0 64rpx;
337
+ font-size: 28rpx;
338
+ color: rgba(0,0,0,0.4);
339
+ line-height: 40rpx;
340
+ }
341
+ .agreement{
342
+ font-size: 24rpx;
343
+ color: rgba(0,0,0,0.2);
344
+ line-height: 34rpx;
345
+ text-align: center;
346
+ }
347
+ }
348
+ </style>