xiaohaizhao 4 months ago
parent
commit
af604f8c97
9 changed files with 388 additions and 13 deletions
  1. 0 3
      App.vue
  2. 3 1
      README.md
  3. 64 0
      components/My-button/My-button.vue
  4. 5 0
      main.js
  5. 10 9
      pages.json
  6. 156 0
      pages/login/login.vue
  7. BIN
      static/image/logo1.png
  8. 70 0
      utils/Http.js
  9. 80 0
      utils/api.js

+ 0 - 3
App.vue

@@ -1,13 +1,10 @@
 <script>
 export default {
 	onLaunch: function () {
-		console.log('App Launch')
 	},
 	onShow: function () {
-		console.log('App Show')
 	},
 	onHide: function () {
-		console.log('App Hide')
 	}
 }
 </script>

+ 3 - 1
README.md

@@ -1 +1,3 @@
-组件库: https://uiadmin.net/uview-plus/components/intro.html
+组件库: https://uiadmin.net/uview-plus/components/intro.html
+
+蓝湖:https://lanhuapp.com/web/#/item/project/stage?tid=76bcae7c-11bb-4157-844e-472f1557d643&pid=3d2ca79c-9dbe-4d61-b7b4-07f02cc1edb0

+ 64 - 0
components/My-button/My-button.vue

@@ -0,0 +1,64 @@
+<template>
+    <view class="button-box" :style="customStyle" :class="disabled && 'disabled'" hover-class="navigator-hover" hover-start-time="50"
+        hover-stay-time="200" @click="handleClick">
+        <view v-if="loading" style="margin-right: 10rpx;">
+            <up-loading-icon size="18" mode="circle" />
+        </view>{{ loading ? loadingText || text + '中...' : text }}
+    </view>
+</template>
+
+<script setup>
+import { defineProps } from 'vue';
+const props = defineProps({
+    text: {
+        type: String,
+        default: '按钮'
+    },
+    loading: {
+        type: Boolean,
+        default: false
+    },
+    loadingText: {
+        type: String
+    },
+    disabled: {
+        type: Boolean,
+        default: false
+    },
+    customStyle: {
+        type: Object
+    },
+    onClick: {
+        type: Function,
+        default: () => { }
+    }
+});
+
+function handleClick() {
+    // 如果处于加载状态或禁用状态,则不执行任何操作
+    if (props.loading || props.disabled) return;
+    // 执行传入的点击事件
+    props.onClick();
+}
+</script>
+
+<style lang="scss" scoped>
+.button-box {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 80rpx;
+    background-color: #3874F6;
+    color: #FFFFFF;
+    box-sizing: border-box;
+    border-radius: 40rpx;
+    font-family: Microsoft YaHei, Microsoft YaHei;
+    font-size: 32rpx;
+    color: #FFFFFF;
+}
+
+.disabled {
+    opacity: 0.4;
+}
+</style>

+ 5 - 0
main.js

@@ -1,5 +1,8 @@
 import App from './App'
 import uviewPlus from '@/uni_modules/uview-plus'
+import {
+  ApiModel
+} from './utils/api'
 
 // #ifndef VUE3
 import Vue from 'vue'
@@ -9,6 +12,7 @@ App.mpType = 'app'
 const app = new Vue({
   ...App
 })
+this.prototype.$Http = new ApiModel();
 app.$mount()
 // #endif
 
@@ -16,6 +20,7 @@ app.$mount()
 import { createSSRApp } from 'vue'
 export function createApp() {
   const app = createSSRApp(App)
+  app.config.globalProperties.$Http = new ApiModel();
   app.use(uviewPlus)
   return {
     app

+ 10 - 9
pages.json

@@ -4,22 +4,23 @@
 		"custom": {
 			"^u--(.*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue",
 			"^up-(.*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue",
-			"^u-([^-].*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue"
+			"^u-([^-].*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue",
+			"^My-(.*)": "@/components/My-$1/My-$1.vue"
 		}
 	},
 	"pages": [
 		{
-			"path": "pages/index/index",
-			"style": {
-				"navigationBarTitleText": "uni-app"
-			}
+			"path": "pages/login/login"
+		},
+		{
+			"path": "pages/index/index"
 		}
 	],
 	"globalStyle": {
-		"navigationBarTextStyle": "black",
-		"navigationBarTitleText": "uni-app",
-		"navigationBarBackgroundColor": "#F8F8F8",
-		"backgroundColor": "#F8F8F8"
+		"navigationBarTextStyle": "white",
+		"navigationBarTitleText": "美大服务",
+		"navigationBarBackgroundColor": "#276BF0",
+		"backgroundColor": "#276BF0"
 	},
 	"uniIdRouter": {}
 }

+ 156 - 0
pages/login/login.vue

@@ -0,0 +1,156 @@
+<template>
+    <view class="head-image">
+        <image src="/static/image/logo1.png" mode="heightFix" />
+    </view>
+    <view class="input-box">
+        <view class="content">
+            <picker class="picker" mode="selector" :range="countryCodes" range-key="name" :value="countryCode"
+                @change="changeCountryCode">
+                {{ countryCode }}
+            </picker>
+            <input type="number" :focus="focused == 'phonenumber'" v-model="phonenumber" placeholder="请输入手机号"
+                class="input" />
+        </view>
+    </view>
+    <view class="input-box" style="margin-top:70rpx;">
+        <view class="content">
+            <input type="number" :focus="focused == 'password'" v-model="password" placeholder="请输入验证码" class="input" />
+            <view class="auth-code" @click="getAuthCode">
+                获取验证码
+            </view>
+        </view>
+    </view>
+    <My-button :customStyle="customStyle" class="my-but" :loading="loading" :disabled="disabled" text="登录"
+        :onClick="logIn" />
+</template>
+
+<script setup>
+import { onLoad } from '@dcloudio/uni-app'
+import { ref, reactive, getCurrentInstance } from 'vue'
+const { $Http } = getCurrentInstance().proxy;
+
+onLoad(() => {
+    console.log('页面加载完成',);
+    /* $Http.basic({
+        "id": 2025072809441203,
+        "content": {
+            "phonenumber": "15988303219",
+        }
+    }).then(res => {
+        console.log('请求结果:', res);
+    }) */
+})
+// 登陆按钮相关
+const loading = ref(false);
+const disabled = ref(true);
+const customStyle = ref({
+    width: '380rpx',
+    margin: '120rpx auto 0',
+});
+// 表单相关
+const focused = ref('');
+const countryCode = ref('+86');
+const phonenumber = ref('15988303219');
+const password = ref('');
+const countryCodes = reactive([
+    { code: '+86', name: '中国 +86', regex: /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/ }, // 中国手机号验证规则
+    { code: '+1', name: '美国 +1', regex: /^[2-9]\d{2}[2-9](?!11)\d{6}$/ }, // 美国手机号验证规则
+    { code: '+44', name: '英国 +44', regex: /^7\d{9}$/ }, // 英国手机号验证规则
+]);
+function validatephonenumber() {
+    const selectedCountry = countryCodes.find(country => country.code === countryCode.value);
+    if (!selectedCountry || !selectedCountry.regex.test(phonenumber.value)) {
+        uni.showToast({
+            title: `请输入有效的${selectedCountry ? selectedCountry.name.split(" ")[0] + '号码' : '手机号'}`,
+            icon: 'none',
+        });
+        focused.value = 'phonenumber'; // 聚焦输入框
+        return false;
+    }
+    return true;
+}
+function changeCountryCode(e) {
+    countryCode.value = countryCodes[e.detail.value].code;
+    if (phonenumber.value) validatephonenumber();
+}
+/* 获取验证码 */
+function getAuthCode() {
+    if (!validatephonenumber()) return;
+    $Http.getpassword({ "phonenumber": phonenumber, "systemclient": "web" }).then(res => {
+        console.log('获取验证码结果:', res);
+        if (res.code == 1) {
+            focused.value = 'password'; // 聚焦输入框
+        }
+        uni.showToast({
+            title: res.msg,
+            icon: 'none',
+        });
+    })
+}
+function logIn() {
+    if (!validatephonenumber()) return;
+    loading.value = true;
+    // 模拟提交逻辑
+    setTimeout(() => {
+        loading.value = false;
+        uni.showToast({
+            title: '提交成功',
+            icon: 'success',
+        });
+    }, 1000);
+}
+</script>
+
+<style lang="scss" scoped>
+.head-image {
+    display: flex;
+    justify-content: center;
+    height: 148rpx;
+    margin-top: 120rpx;
+    margin-bottom: 120rpx;
+
+    image {
+        height: 100%;
+    }
+}
+
+.input-box {
+    width: 630rpx;
+    padding-bottom: 20rpx;
+    margin: 0 auto;
+    border-bottom: 1px solid #dcdcdc;
+    box-sizing: border-box;
+
+    .content {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        height: 48rpx;
+        width: 100%;
+
+        .picker {
+            font-family: Microsoft YaHei, Microsoft YaHei;
+            font-weight: bold;
+            font-size: 32rpx;
+            color: #333333;
+            margin-right: 20rpx;
+        }
+
+        .input {
+            flex: 1;
+        }
+
+        .auth-code {
+            margin-left: 20rpx;
+            font-family: Microsoft YaHei, Microsoft YaHei;
+            font-weight: bold;
+            font-size: 28rpx;
+            color: #3874F6;
+        }
+    }
+}
+
+.my-but {
+    width: 380rpx;
+}
+</style>

BIN
static/image/logo1.png


+ 70 - 0
utils/Http.js

@@ -0,0 +1,70 @@
+class HTTP {
+    constructor() {
+        this.urls = [{
+            name: '测试',
+            url: "http://61.164.207.46:8300"
+        }, {
+            name: '正式',
+            url: "https://crm.meida.com:16691"
+        }, {
+            name: "楚楚",
+            url: "https://cucu.cnyunl.com:8079"
+        }]
+        if (process.env.NODE_ENV === 'development') {
+            this.baseUrl = this.urls[0].url;
+        } else {
+            this.baseUrl = this.urls[1].url;
+        }
+        console.log("接口地址", this.baseUrl)
+    }
+    request({
+        url,
+        data = {},
+        method = "POST",
+        header = {
+            'content-type': 'application/json'
+        },
+        showLoading = ''
+    }) {
+        return new Promise((resolve, reject) => {
+            this._request(url, resolve, reject, data, method, header, showLoading);
+        })
+    }
+    _request(url, resolve, reject, data, method, header, showLoading) {
+        if (showLoading) uni.showLoading({
+            title: showLoading,
+            mask: true
+        })
+        uni.request({
+            url: this.baseUrl + '/yos/rest' + url,
+            data: data,
+            method: method,
+            header: header,
+            timeout: 60000,
+            success: res => resolve(res.data),
+            fial: err => reject(err),
+            complete: (res) => {
+                if (showLoading) uni.hideLoading()
+                if (res.errMsg != 'request:ok') {
+                    uni.showToast({
+                        title: '网络异常,请稍后再试',
+                        icon: "none"
+                    })
+                } else if (res.data.msg == '登陆状态已过期,请重新登陆!') {
+                    uni.redirectTo({
+                        url: '/pages/login/login',
+                        success() {
+                            uni.showToast({
+                                title: res.msg,
+                                icon: "none"
+                            })
+                        }
+                    });
+                }
+            }
+        })
+    }
+}
+export {
+    HTTP
+}

+ 80 - 0
utils/api.js

@@ -0,0 +1,80 @@
+import {
+    HTTP
+} from './Http.js'
+class ApiModel extends HTTP {
+    devicevaluecheck(data) {
+        data.accesstoken = wx.getStorageSync('userMsg').token;
+        return this.request({
+            url: "/simple/devicevaluecheck",
+            data
+        })
+    }
+    loginbywechat(data) {
+        return this.request({
+            url: "/index/loginbywechat",
+            data
+        })
+    }
+    /* 登录 */
+    login(data) {
+        return this.request({
+            url: "/index/loginbyaccount",
+            data
+        })
+    }
+    /* 验证码登录 */
+    plogin(data) {
+        return this.request({
+            url: "/index/login",
+            data
+        })
+    }
+    /* 获取验证码 */
+    getpassword(data) {
+        return this.request({
+            url: "/index/getpassword",
+            data
+        })
+    }
+    /* 有状态通用 */
+    basic(data, loading = true) {
+        data.accesstoken = wx.getStorageSync('userMsg').token;
+        return this.request({
+            url: "/index",
+            data,
+            loading
+        })
+    }
+    /* 无状态 */
+    base(data, loading = true) {
+        return this.request({
+            url: "/index",
+            data,
+            loading
+        })
+    }
+    /* 退出登录 */
+    logout() {
+        let data = {
+            accesstoken: wx.getStorageSync('userMsg').token
+        }
+        return this.request({
+            url: "/index/logout",
+            data
+        })
+    }
+    /* 获取地区code */
+    getLocationCode() {
+        return this.request({
+            url: "/index/getforward?url=" + encodeURIComponent("http://www.nmc.cn/rest/position"),
+            data: {},
+            method: "GET",
+            header: {
+                "Access-Control-Allow-Origin": "*"
+            }
+        })
+    }
+}
+export {
+    ApiModel
+}