Kaynağa Gözat

Merge branch 'master' of https://git.citupro.com/zhengnaiwen_citu/menduner-uniapp

lifanagju_citu 8 ay önce
ebeveyn
işleme
a0d28b91a4

+ 0 - 31
api/auth.js

@@ -1,31 +0,0 @@
-import request from "@/utils/request"
-
-// 刷新令牌
-export const refreshToken = async (refreshToken) => {
-  return await request.post({
-    url: '/menduner/system/auth/refresh-token',
-    params: {
-      refreshToken
-    },
-    custom: {
-      showLoading: false,
-      showError: false
-    }
-  })
-}
-
-// 发送手机验证码
-export const sendSmsCode = async (mobile, scene) => {
-  return await request.post({
-    url: '/menduner/system/auth/send-sms-code',
-    data: {
-      phone: mobile,
-      scene
-    },
-    custom: {
-      loadingMsg: '发送中',
-      showSuccess: true,
-      successMsg: '发送成功'
-    }
-  })
-}

+ 79 - 0
api/common.js

@@ -0,0 +1,79 @@
+import request from "@/utils/request"
+
+// 刷新令牌
+export const refreshToken = (refreshToken) => {
+  return request({
+    url: '/menduner/system/auth/refresh-token',
+    method: "POST",
+    params: {
+      refreshToken
+    },
+    custom: {
+      showLoading: false,
+      showError: false
+    }
+  })
+}
+
+// 发送手机验证码
+export const sendSmsCode = (data) => {
+  return request({
+    url: '/menduner/system/auth/send-sms-code',
+    method: "POST",
+    data,
+    custom: {
+      loadingMsg: '发送中',
+      showSuccess: true,
+      successMsg: '发送成功'
+    }
+  })
+}
+
+// 短信登录
+export const smsLogin = (data) => {
+  return request({
+    url: '/menduner/system/auth/sms-login',
+    method: 'POST',
+    data,
+    custom: {
+      showLoading: false
+    }
+  })
+}
+
+// 密码登录
+export const passwordLogin = (data) => {
+  return request({
+    url: '/menduner/system/auth/login',
+    method: 'POST',
+    data,
+    custom: {
+      showLoading: false
+    }
+  })
+}
+
+// 退出登录
+export const logout = () => {
+  return request({
+    url: '/menduner/system/auth/logout',
+    method: 'POST',
+    custom: {
+      showLoading: false,
+      auth: true
+    }
+  })
+}
+
+// 字典
+export const getDictData = (params) => {
+  return request({
+    url: '/system/dict-data/type',
+    method: 'GET',
+    params,
+    custom: {
+      showLoading: false,
+      auth: true
+    }
+  })
+}

+ 15 - 2
api/user.js

@@ -1,13 +1,26 @@
 import request from "@/utils/request"
 import request from "@/utils/request"
 
 
 // 获取用户基本信息
 // 获取用户基本信息
-export const getUserInfo = async (params) => {
-  return await request.get({
+export const getUserInfo = (params) => {
+  return request({
     url: '/menduner/system/person/get',
     url: '/menduner/system/person/get',
+    method: 'GET',
     params,
     params,
     custom: {
     custom: {
       showLoading: false,
       showLoading: false,
       auth: true
       auth: true
     }
     }
   })
   })
+}
+
+// 获取附件列表
+export const getPersonResumeCv = () => {
+  return request({
+    url: '/menduner/system/person/resume/get/person/cv',
+    method: 'GET',
+    custom: {
+      showLoading: false,
+      auth: true
+    }
+  })
 }
 }

+ 0 - 134
components/AuthModal/index.vue

@@ -1,134 +0,0 @@
-<template>
-  <view>
-    <uni-popup ref="popup" background-color="#fff" type="bottom">
-      <view class="head-box ss-p-30">
-        <view class="ss-flex ss-m-b-20">
-          <view class="head-title head-title-line head-title-animation" :class="{ 'head-title-active': type === 'account' }" @tap="type = 'code'">短信登录</view>
-          <view class="head-title  ss-m-r-40" :class="{ 'head-title-active': type === 'code' }" @tap="type = 'account'">账号登录</view>
-        </view>
-        <view v-if="type === 'code'" class="head-subtitle">未注册的手机号,验证后自动注册账号</view>
-      </view>
-
-      <view class="ss-p-30 ss-m-b-60">
-        <!-- 短信验证码登录 -->
-        <uni-forms
-          v-if="type === 'code'"
-          ref="smsLoginRef"
-          v-model="state.sms"
-          :rules="state.smsRules"
-          validateTrigger="bind"
-          labelWidth="140"
-          labelAlign="center"
-        >
-          <uni-forms-item name="phone" label="手机号">
-            <uni-easyinput
-              placeholder="请输入手机号"
-              v-model="state.sms.phone"
-              :inputBorder="false"
-              type="number"
-            >
-              <template v-slot:right>
-                <button
-                  class="ss-reset-button code-btn code-btn-start"
-                  :disabled="state.isMobileEnd"
-                  :class="{ 'code-btn-end': state.isMobileEnd }"
-                  @tap="handleSendCode"
-                >
-                  <!-- {{ getSmsTimer('smsLogin') }} -->
-                </button>
-              </template>
-            </uni-easyinput>
-          </uni-forms-item>
-
-          <uni-forms-item name="code" label="验证码">
-            <uni-easyinput
-              placeholder="请输入验证码"
-              v-model="state.sms.code"
-              :inputBorder="false"
-              type="number"
-              maxlength="6"
-            >
-              <template v-slot:right>
-                <button class="ss-reset-button login-btn-start" @tap="smsLoginSubmit"> 登录 </button>
-              </template>
-            </uni-easyinput>
-          </uni-forms-item>
-        </uni-forms>
-        <!-- 账号密码登录 -->
-        <uni-forms
-          v-if="type === 'account'"
-          ref="accountLoginRef"
-          v-model="state.account"
-          :rules="state.rules"
-          validateTrigger="bind"
-          labelWidth="140"
-          labelAlign="center"
-        >
-          <uni-forms-item name="phone" label="账号">
-            <uni-easyinput placeholder="请输入账号" v-model="state.account.phone" :inputBorder="false"></uni-easyinput>
-          </uni-forms-item>
-
-          <uni-forms-item name="password" label="密码">
-            <uni-easyinput
-              type="password"
-              placeholder="请输入密码"
-              v-model="state.account.password"
-              :inputBorder="false"
-            >
-              <template v-slot:right>
-                <button class="ss-reset-button login-btn-start" @tap="accountLoginSubmit">登录</button>
-              </template>
-            </uni-easyinput>
-          </uni-forms-item>
-        </uni-forms>
-      </view>
-		</uni-popup>
-  </view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { mobile, password, code } from '@/utils/validate'
-// import { getSmsTimer } from '@/hooks/useModal'
-
-const popup = ref()
-const type = ref('code')
-const accountLoginRef = ref()
-const smsLoginRef = ref()
-const state = ref({
-  isMobileEnd: false, // 手机号输入完毕
-  codeText: '获取验证码',
-  sms: {
-    phone: '13229740092',
-    code: ''
-  },
-  account: {
-    phone: '13229740091',
-    password: 'Citu123'
-  },
-  rules: {
-    phone: mobile,
-    password,
-  },
-  smsRules: {
-    code,
-    phone: mobile
-  }
-})
-
-const open = () => {
-  popup.value.open()
-}
-
-const accountLoginSubmit = () => {}
-const smsLoginSubmit = () => {}
-
-defineExpose({
-  open,
-  popup
-})
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 9 - 1
main.js

@@ -8,7 +8,7 @@ Vue.config.productionTip = false
 App.mpType = 'app'
 App.mpType = 'app'
 
 
 const app = new Vue({
 const app = new Vue({
-    ...App
+  ...App
 })
 })
 app.$mount()
 app.$mount()
 // #endif
 // #endif
@@ -16,8 +16,16 @@ app.$mount()
 // #ifdef VUE3
 // #ifdef VUE3
 import { createSSRApp } from 'vue'
 import { createSSRApp } from 'vue'
 import App from './App.vue'
 import App from './App.vue'
+import { createPinia } from 'pinia'
+import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
+const pinia = createPinia()
+pinia.use(piniaPluginPersistedstate)
+
 export function createApp() {
 export function createApp() {
   const app = createSSRApp(App)
   const app = createSSRApp(App)
+
+  app.use(pinia)
+
   return {
   return {
     app
     app
   }
   }

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1461 - 18
package-lock.json


+ 2 - 1
package.json

@@ -4,6 +4,7 @@
     "lodash-es": "^4.17.21",
     "lodash-es": "^4.17.21",
     "luch-request": "^3.1.1",
     "luch-request": "^3.1.1",
     "pinia": "^2.2.2",
     "pinia": "^2.2.2",
-    "pinia-plugin-persist-uni": "^1.3.1"
+    "pinia-plugin-persist-uni": "^1.3.1",
+    "pinia-plugin-persistedstate": "^4.0.1"
   }
   }
 }
 }

+ 19 - 0
pages.json

@@ -25,6 +25,25 @@
 			}
 			}
 		}
 		}
 	],
 	],
+	"subPackages": [
+		{
+			"root": "pagesA",
+			"pages": [
+				{
+					"path": "resume/index",
+					"style": {
+						"navigationBarTitleText": "我的简历"
+					}
+				},
+				{
+					"path": "collect/position",
+					"style": {
+						"navigationBarTitleText": "职位收藏"
+					}
+				}
+			]
+		}
+	],
 	"globalStyle": {
 	"globalStyle": {
 		"navigationBarTextStyle": "black",
 		"navigationBarTextStyle": "black",
 		"navigationBarTitleText": "门墩儿招聘",
 		"navigationBarTitleText": "门墩儿招聘",

+ 58 - 25
pages/index/my.vue

@@ -1,34 +1,45 @@
 <template>
 <template>
-  <view>
-    <view class="text-center" @tap="handleLogin">
-      <img src="https://minio.citupro.com/dev/menduner/7.png" alt="" class="img-box">
-      <view class="font-weight-bold font-size-20">点击登录</view>
+  <view class="ss-p-b-30">
+    <view class="text-center">
+      <img :src="getUserAvatar(userInfo?.avatar, userInfo?.sex)" alt="" class="img-box">
+      <view v-if="!useUserStore.isLogin" class="font-weight-bold font-size-20" @tap="handleLogin">点击登录</view>
+      <view v-else class="font-weight-bold font-size-20">{{ userInfo.name || userInfo.phone }}</view>
     </view>
     </view>
     <view style="margin-top: 80rpx;">
     <view style="margin-top: 80rpx;">
-		<uni-grid :column="4" :show-border="false">
-			<uni-grid-item :index="0" v-for="(val, index) in grid" :key="index" class="text-center">
-				<uni-icons :type="val.icon" size="40" color="#00897B"></uni-icons>
-				<text class="font-size-13 color-999 mt-5">{{ val.title }}</text>
-			</uni-grid-item>
-		</uni-grid>
+      <uni-grid :column="4" :show-border="false">
+        <uni-grid-item :index="0" v-for="(val, index) in grid" :key="index" class="text-center">
+          <uni-icons :type="val.icon" size="40" color="#00897B"></uni-icons>
+          <text class="font-size-13 color-999 mt-5">{{ val.title }}</text>
+        </uni-grid-item>
+      </uni-grid>
+      </view>
+      <view style="height: 10rpx; background-color: #f8f8fa;"></view>
+
+      <view class="card">
+      <uni-list>
+        <uni-list-item v-for="item in list" :clickable="true" :key="item.title" :title="item.title" showArrow :rightText="item.rightTex || ''" @click="handleToLink(item)"></uni-list-item>
+      </uni-list>
     </view>
     </view>
-    <view style="height: 10rpx; background-color: #f8f8fa;"></view>
 
 
-    <view class="card">
-		<uni-list>
-			<uni-list-item v-for="item in list" :key="item.title" :title="item.title" link showArrow :rightText="item.rightTex || ''"></uni-list-item>
-		</uni-list>
-	</view>
+    <button v-if="useUserStore.isLogin" class="send-button" @tap="handleLogout">退出登录</button>
 
 
-    <AuthModal ref="authModal"></AuthModal>
+    <uni-popup ref="popup" type="dialog">
+			<uni-popup-dialog type="warn" cancelText="取消" confirmText="确定" title="系统提示" content="确认退出账号?" @confirm="handleLogoutConfirm"
+				@close="handleLogoutClose"></uni-popup-dialog>
+		</uni-popup>
   </view>
   </view>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { ref } from 'vue'
-import AuthModal from '@/components/AuthModal'
+import { ref, computed } from 'vue'
+import { userStore } from '@/store/user'
+import { getUserAvatar } from '@/utils/avatar'
 
 
-const authModal = ref()
+const useUserStore = userStore()
+const userInfo = computed(() => {
+  return useUserStore.userInfo
+})
+const popup = ref()
 const grid = [
 const grid = [
   { title: '全部', icon: 'list' },
   { title: '全部', icon: 'list' },
   { title: '被查看', icon: 'eye-filled' },
   { title: '被查看', icon: 'eye-filled' },
@@ -37,14 +48,36 @@ const grid = [
 ]
 ]
 
 
 const list = [
 const list = [
-	{	title:'我的简历',	path:''	},					
-	{ title:'职位订阅', path:'' },
-	{	title:'意见反馈',	path:'' },
-	{ title:'切换为招聘者', path:'', rightTex: '我要招人' }
+	{	title:'我的简历',	path:'/pagesA/resume/index'	},					
+	{ title:'职位收藏', path:'/pagesA/collect/position' },
+	{ title:'切换为招聘者', rightTex: '我要招人' }
 ]
 ]
 
 
+// 列表跳转
+const handleToLink = (item) => {
+  if (item.path) {
+    uni.navigateTo({
+      url: item.path
+    })
+  }
+}
+
+// 登录
 const handleLogin = () => {
 const handleLogin = () => {
-  authModal.value.open()
+  uni.navigateTo({
+    url: '/pages/login/index'
+  })
+}
+
+// 退出登录
+const handleLogout = () => {
+  popup.value.open()
+}
+const handleLogoutClose = () => {
+  popup.value.close()
+}
+const handleLogoutConfirm = () => {
+  useUserStore.handleLogout()
 }
 }
 </script>
 </script>
 
 

+ 114 - 6
pages/login/index.vue

@@ -1,18 +1,126 @@
 <template>
 <template>
-  <view>
+  <view class="ss-p-30 head-box">
     <view>欢迎来到门墩儿招聘</view>
     <view>欢迎来到门墩儿招聘</view>
-    <uni-segmented-control :current="current" :values="items" style-type="button" active-color="#00897B" @clickItem="onClickItem" />
+    <uni-segmented-control class="ss-m-t-60" :current="current" :values="items" style-type="text" active-color="#00897B" @clickItem="onClickItem" />
+    <view class="head-subtitle ss-m-t-10">未注册的手机号,验证后自动注册账号</view>
+
+    <view class="ss-m-t-30">
+      <!-- 短信验证码登录 -->
+      <uni-forms
+        v-if="current === 0"
+        ref="smsLoginRef"
+        v-model="state.sms"
+        :rules="state.smsRules"
+        validateTrigger="bind"
+        labelWidth="140"
+        labelAlign="center"
+      >
+        <uni-forms-item name="phone" label="手机号">
+          <uni-easyinput placeholder="请输入手机号" v-model="state.sms.phone" :inputBorder="false" type="number">
+            <template v-slot:right>
+              <button class="login-code" :disabled="state.isMobileEnd" :class="{ 'code-btn-end': state.isMobileEnd }" @tap="handleCode">
+                {{ getSmsTimer('smsLogin') }}
+              </button>
+            </template>
+          </uni-easyinput>
+        </uni-forms-item>
+
+        <uni-forms-item name="code" label="验证码">
+          <uni-easyinput placeholder="请输入验证码" v-model="state.sms.code" :inputBorder="false" type="number" maxlength="6"></uni-easyinput>
+        </uni-forms-item>
+      </uni-forms>
+
+      <!-- 账号密码登录 -->
+      <uni-forms
+        v-else
+        ref="accountLoginRef"
+        v-model="state.account"
+        :rules="state.rules"
+        validateTrigger="bind"
+        labelWidth="140"
+        labelAlign="center"
+      >
+        <uni-forms-item name="phone" label="账号">
+          <uni-easyinput placeholder="请输入账号" v-model="state.account.phone" :inputBorder="false"></uni-easyinput>
+        </uni-forms-item>
+
+        <uni-forms-item name="password" label="密码">
+          <uni-easyinput type="password" placeholder="请输入密码" v-model="state.account.password" :inputBorder="false"></uni-easyinput>
+        </uni-forms-item>
+      </uni-forms>
+
+      <button class="send-button" @tap="handleLogin"> 登录/注册 </button>
+    </view>
   </view>
   </view>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { ref } from 'vue'
+import { ref, unref } from 'vue'
+import { mobile, password, code } from '@/utils/validate'
+import { getSmsCode, getSmsTimer } from '@/utils/code'
+import { userStore } from '@/store/user'
+
+const useUserStore = userStore()
 const items = ['短信登录', '账号登录']
 const items = ['短信登录', '账号登录']
-const current = ref(0)
+const current = ref(1)
+const accountLoginRef = ref()
+const smsLoginRef = ref()
+const state = ref({
+  isMobileEnd: false, // 手机号输入完毕
+  codeText: '获取验证码',
+  sms: {
+    phone: '13229740092',
+    code: ''
+  },
+  account: {
+    phone: '13229740091',
+    password: 'Citu123'
+  },
+  rules: {
+    phone: mobile,
+    password,
+  },
+  smsRules: {
+    code,
+    phone: mobile
+  }
+})
+
+const onClickItem = (e) => {
+  current.value = e.currentIndex
+}
 
 
-const onClickItem = (e) => {}
+// 获取验证码
+const handleCode = () => {
+  if (!state.value.sms.phone) {
+    uni.showToast({
+      title: '请输入手机号',
+      icon: 'none',
+      duration: 2000
+    })
+    return
+  }
+  getSmsCode('smsLogin', state.value.sms.phone)
+}
+
+// 登录
+const handleLogin = async () => {
+  const validate = await unref(current.value === 0 ? smsLoginRef : accountLoginRef).validate()
+  if (!validate) return
+  await useUserStore.handleSmsLogin(current.value === 0 ? state.value.sms : state.value.account, current.value === 0 ? true : false)
+}
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-
+.login-code {
+  width: 73px;
+  min-width: 73px;
+  color: var(--v-primary-base);
+  text-align: center; 
+  font-size: 12px; 
+  cursor: pointer;
+  border: 1px dashed var(--v-primary-base);
+  border-radius: 26px;
+  padding: 0;
+}
 </style>
 </style>

+ 10 - 0
pagesA/collect/position.vue

@@ -0,0 +1,10 @@
+<template>
+  <div>position</div>
+</template>
+
+<script setup>
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 22 - 0
pagesA/resume/index.vue

@@ -0,0 +1,22 @@
+<template>
+  <view>
+    <button class="send-button">从微信导入简历</button>
+  </view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { getPersonResumeCv } from '@/api/user'
+
+// 获取附件
+const attachmentList = ref([])
+const getList = async () => {
+  const data = await getPersonResumeCv()
+  attachmentList.value = data
+}
+getList()
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 45 - 0
static/style/index.css

@@ -8965,3 +8965,48 @@
   font-weight: 500;
   font-weight: 500;
   color: #fff;
   color: #fff;
 }
 }
+
+.recomm-button {
+  width: 85%;
+  height: 44px;
+  line-height: 44px;
+  margin: 20px auto;
+  background-color: #00897B !important;
+}
+
+.second-button {
+  width: 50vw;
+  height: 44px;
+  margin: 15px;
+  background-color: #00897B !important;
+}
+
+.second-button:first-child {
+  margin: 15px 0 15px 15px;
+}
+
+.bottom-sticky {
+  display: flex;
+  width: 100vw;
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  background-image: linear-gradient(rgba(255, 255, 255, 0.8), white);
+}
+
+.send-button {
+  width: 90vw;
+  height: 44px;
+  line-height: 44px;
+  margin: 20px auto;
+  background-color: #00897B !important;
+  color: #fff;
+}
+
+.disabled-button {
+  width: 85%;
+  height: 44px;
+  line-height: 44px;
+  margin: 20px auto;
+  background-color: grey !important;
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
static/style/index.min.css


+ 49 - 0
static/style/index.scss

@@ -347,4 +347,53 @@
   font-size: 26rpx;
   font-size: 26rpx;
   font-weight: 500;
   font-weight: 500;
   color: #fff;
   color: #fff;
+}
+
+//页面底部单个按钮
+.recomm-button {
+  width: 85%;
+  height: 44px;
+  line-height: 44px;
+  margin: 20px auto;
+  background-color: #00897B !important;
+  // border-radius: 25px;
+}
+//页面底部两个按钮
+.second-button {
+  width: 50vw;
+  height: 44px;
+  margin: 15px;
+  background-color: #00897B !important;
+  // border-radius: 25px;
+}
+.second-button:first-child {
+	margin: 15px 0 15px 15px;
+}
+//底部按钮公用定位
+.bottom-sticky{
+  display: flex;
+  width:100vw;
+  position: fixed;
+  bottom:0;
+  left: 0;
+  background-image:linear-gradient(rgba(255,255,255,0.8),white);
+}
+// 主要页面大按钮用这个
+.send-button {
+	width: 90vw;
+	height:44px;
+	line-height: 44px;
+	margin:20px auto;
+	background-color: #00897B !important;
+	// border-radius: 25px;
+	color: #fff;
+}
+//禁用按钮
+.disabled-button {
+	width: 85%;
+  height: 44px;
+  line-height: 44px;
+  margin: 20px auto;
+  background-color: grey !important;
+  // border-radius: 25px;
 }
 }

+ 0 - 20
store/index.js

@@ -1,20 +0,0 @@
-import { createPinia } from 'pinia';
-import piniaPersist from 'pinia-plugin-persist-uni';
-
-// 自动注入所有pinia模块
-const files = import.meta.glob('./*.js', { eager: true });
-const modules = {};
-Object.keys(files).forEach((key) => {
-  modules[key.replace(/(.*\/)*([^.]+).*/gi, '$2')] = files[key].default;
-});
-
-export const setupPinia = (app) => {
-  const pinia = createPinia();
-  pinia.use(piniaPersist);
-
-  app.use(pinia);
-};
-
-export default (name) => {
-  return modules[name]();
-};

+ 23 - 0
store/modal.js

@@ -0,0 +1,23 @@
+import { defineStore } from 'pinia';
+
+export const modalStore = defineStore({
+  id: 'modal',
+  state: () => ({
+    lastTimer: {
+      // 短信验证码计时器,为了防止刷新请求做了持久化
+      smsLogin: 0,
+      changeMobile: 0,
+      resetPassword: 0,
+      changePassword: 0,
+    }
+  }),
+  persist: {
+    enabled: true,
+    strategies: [
+      {
+        key: 'modal-store',
+        paths: ['lastTimer', 'advHistory'],
+      },
+    ],
+  },
+});

+ 21 - 6
store/user.js

@@ -1,6 +1,7 @@
 import { defineStore } from 'pinia';
 import { defineStore } from 'pinia';
 import { clone, cloneDeep } from 'lodash-es';
 import { clone, cloneDeep } from 'lodash-es';
 import { getUserInfo } from '@/api/user';
 import { getUserInfo } from '@/api/user';
+import { smsLogin, passwordLogin, logout } from '@/api/common'
 
 
 // 默认用户信息
 // 默认用户信息
 const defaultUserInfo = {
 const defaultUserInfo = {
@@ -20,7 +21,7 @@ const defaultAccountInfo = {
   userId: ''
   userId: ''
 }
 }
 
 
-export const user = defineStore({
+export const userStore = defineStore({
   id: 'user',
   id: 'user',
   state: () => ({
   state: () => ({
     userInfo: {}, // 用户信息
     userInfo: {}, // 用户信息
@@ -30,6 +31,21 @@ export const user = defineStore({
   }),
   }),
 
 
   actions: {
   actions: {
+    // 登录
+    async handleSmsLogin (query, type) {
+      const api = type ? smsLogin : passwordLogin
+      const { data, code } = await api(query)
+      if (code === 0) {
+        uni.showToast({
+          title: '登录成功'
+        })
+      }
+      this.accountInfo = data
+      this.getInfo()
+      uni.switchTab({
+        url: '/pages/index/my'
+      })
+    },
     // 获取用户信息
     // 获取用户信息
     async getInfo() {
     async getInfo() {
       const { code, data } = await getUserInfo({ userId: this.accountInfo.userId });
       const { code, data } = await getUserInfo({ userId: this.accountInfo.userId });
@@ -69,7 +85,7 @@ export const user = defineStore({
 
 
       // 获取最新信息
       // 获取最新信息
       // await this.getInfo();
       // await this.getInfo();
-      this.getWallet();
+      // this.getWallet();
       return this.userInfo;
       return this.userInfo;
     },
     },
 
 
@@ -88,7 +104,8 @@ export const user = defineStore({
     },
     },
 
 
     // 登出系统
     // 登出系统
-    async logout() {
+    async handleLogout() {
+      await logout()
       this.resetUserData();
       this.resetUserData();
       return !this.isLogin;
       return !this.isLogin;
     },
     },
@@ -101,6 +118,4 @@ export const user = defineStore({
       },
       },
     ],
     ],
   },
   },
-});
-
-export default user;
+});

+ 10 - 0
utils/avatar.js

@@ -0,0 +1,10 @@
+const male = 'https://minio.citupro.com/dev/menduner/11.png'
+const female = 'https://minio.citupro.com/dev/menduner/7.png'
+
+// 根据性别返回默认头像
+export const getUserAvatar = (avatar, sex) => {
+  if (avatar) return avatar
+  if (!sex) return female
+  if (sex === '1') return male
+  else return female
+}

+ 88 - 0
utils/code.js

@@ -0,0 +1,88 @@
+import { ref } from 'vue'
+import { sendSmsCode } from '@/api/common'
+import { modalStore } from '@/store/modal'
+import dayjs from 'dayjs';
+import test from '@/utils/test'
+
+const modal = modalStore()
+// 发送验证码
+export const getSmsCode = (event, mobile) => {
+  const lastSendTimer = modal.lastTimer[event];
+  if (typeof lastSendTimer === 'undefined') {
+    uni.showToast({
+      title: '短信发送事件错误'
+    })
+    return;
+  }
+
+  const duration = dayjs().unix() - lastSendTimer;
+  const canSend = duration >= 60;
+  if (!canSend) {
+    uni.showToast({
+      title: '请稍后再试'
+    })
+    return;
+  }
+  // 只有 mobile 非空时才校验。因为部分场景(修改密码),不需要输入手机
+  if (mobile && !test.mobile(mobile)) {
+    uni.showToast({
+      title: '手机号码格式不正确'
+    })
+    return;
+  }
+
+  // 发送验证码 + 更新上次发送验证码时间
+  let scene = -1;
+  switch (event) {
+    case 'resetPassword':
+      scene = 4;
+      break;
+    case 'changePassword':
+      scene = 3;
+      break;
+    case 'changeMobile':
+      scene = 2;
+      break;
+    case 'smsLogin':
+      scene = 30; // 对接门墩短信登录
+      break;
+  }
+  sendSmsCode({ phone: mobile, scene }).then((res) => {
+    if (res.code === 0) {
+      uni.showToast({
+        title: '发送成功,请注意查收',
+        icon: 'success',
+        duration: 2000
+      })
+      modal.$patch((state) => {
+        state.lastTimer[event] = dayjs().unix();
+      })
+    }
+  })
+}
+
+// 验证码倒计时
+export const getSmsTimer = (event) => {
+  const lastSendTimer = modal.lastTimer[event]
+
+  if (typeof lastSendTimer === 'undefined') {
+    uni.showToast({
+      title: '短信发送事件错误'
+    })
+    return
+  }
+
+  const duration = ref(dayjs().unix() - lastSendTimer - 60)
+  const canSend = duration.value >= 0
+
+  if (canSend) {
+    return '获取验证码'
+  }
+
+  if (!canSend) {
+    setTimeout(() => {
+      duration.value++;
+    }, 1000);
+    return -duration.value.toString() + ' 秒'
+  }
+}

+ 24 - 14
utils/request.js

@@ -4,9 +4,8 @@
  */
  */
 
 
 import Request from 'luch-request';
 import Request from 'luch-request';
-// import { showAuthModal } from '@/sheep/hooks/useModal';
-import { refreshToken } from '@/api/auth';
-import { user } from '@/store/user'
+import { refreshToken } from '@/api/common';
+import { userStore } from '@/store/user'
 
 
 const baseUrl = 'http://menduner.citupro.com:7878'
 const baseUrl = 'http://menduner.citupro.com:7878'
 const tenantId = '155'
 const tenantId = '155'
@@ -69,11 +68,16 @@ const http = new Request({
  */
  */
 http.interceptors.request.use(
 http.interceptors.request.use(
 	(config) => {
 	(config) => {
-    const useUserStore = user()
+    const useUserStore = userStore()
     // 自定义处理【auth 授权】:必须登录的接口,则跳出 AuthModal 登录弹窗
     // 自定义处理【auth 授权】:必须登录的接口,则跳出 AuthModal 登录弹窗
 		if (config.custom.auth && !useUserStore.isLogin) {
 		if (config.custom.auth && !useUserStore.isLogin) {
-		// 	showAuthModal();
-    console.log('必须登录========')
+			uni.showToast({
+				title:'请先登录',
+				icon: 'none'
+			})
+			uni.navigateTo({
+				url: '/pages/login/index'
+			})
 			return Promise.reject();
 			return Promise.reject();
 		}
 		}
 
 
@@ -113,8 +117,8 @@ http.interceptors.response.use(
 	(response) => {
 	(response) => {
 		// 约定:如果是 /auth/ 下的 URL 地址,并且返回了 accessToken 说明是登录相关的接口,则自动设置登陆令牌
 		// 约定:如果是 /auth/ 下的 URL 地址,并且返回了 accessToken 说明是登录相关的接口,则自动设置登陆令牌
 		if (response.config.url.indexOf('/system/auth/') >= 0 && response.data?.data?.accessToken) {
 		if (response.config.url.indexOf('/system/auth/') >= 0 && response.data?.data?.accessToken) {
-			const userStore = user()
-			userStore.setToken(response.data.data.accessToken, response.data.data.refreshToken);
+			const useUserStore = userStore()
+			useUserStore.setToken(response.data.data.accessToken, response.data.data.refreshToken);
 		}
 		}
 
 
     // 自定处理【loading 加载中】:如果需要显示 loading,则关闭 loading
     // 自定处理【loading 加载中】:如果需要显示 loading,则关闭 loading
@@ -151,8 +155,8 @@ http.interceptors.response.use(
 		return Promise.resolve(response.data);
 		return Promise.resolve(response.data);
 	},
 	},
 	(error) => {
 	(error) => {
-		const userStore = user()
-		const isLogin = userStore.isLogin;
+		const useUserStore = userStore()
+		const isLogin = useUserStore.isLogin;
 		let errorMessage = '网络请求出错';
 		let errorMessage = '网络请求出错';
 		if (error !== undefined) {
 		if (error !== undefined) {
 			switch (error.statusCode) {
 			switch (error.statusCode) {
@@ -275,13 +279,19 @@ const handleRefreshToken = async (config) => {
  * 处理 401 未登录的错误
  * 处理 401 未登录的错误
  */
  */
 const handleAuthorized = () => {
 const handleAuthorized = () => {
-  const userStore = user()
-  userStore.logout(true);
-  // showAuthModal();
+  const useUserStore = userStore()
+  useUserStore.handleLogout(true);
+  uni.showToast({
+		title:'请先登录',
+		icon: 'none'
+	})
+	uni.navigateTo({
+		url: '/pages/login/index'
+	})
   // 登录超时
   // 登录超时
   return Promise.reject({
   return Promise.reject({
     code: 401,
     code: 401,
-    msg: userStore.isLogin ? '您的登陆已过期' : '请先登录'
+    msg: useUserStore.isLogin ? '您的登陆已过期' : '请先登录'
   })
   })
 }
 }
 
 

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor