tabbar switch

main
王文龙 2023-12-12 15:31:53 +08:00
parent f28cc3108f
commit 9c12333c73
11 changed files with 335 additions and 161 deletions

View File

@ -69,7 +69,7 @@
"uview-plus": "^3.1.41", "uview-plus": "^3.1.41",
"vue": "3.2.47", "vue": "3.2.47",
"vue-i18n": "^9.1.9", "vue-i18n": "^9.1.9",
"z-paging": "^2.5.8" "z-paging": "^2.6.3"
}, },
"devDependencies": { "devDependencies": {
"@dcloudio/types": "^3.3.2", "@dcloudio/types": "^3.3.2",

View File

@ -7,6 +7,7 @@ import request from '@/utils/request/index.js'
export const userLogin = data => export const userLogin = data =>
// mock({ ...data, mockData: { token: 'mock-token' } }) // mock({ ...data, mockData: { token: 'mock-token' } })
request.post('/wxlogin', data) request.post('/wxlogin', data)
/** /**
* @description 保存用户信息 * @description 保存用户信息
*/ */
@ -27,6 +28,20 @@ export const getUser = params =>
// mock({ ...data, mockData: { token: 'mock-token' } }) // mock({ ...data, mockData: { token: 'mock-token' } })
request.get('/wxUser/info', params) request.get('/wxUser/info', params)
/**
* @description 陪诊师申请信息
*/
export const doctorSave = data =>
request.post('/doctor/save', data)
/**
* @description 获取陪诊师信息
*/
export const doctorInfo = data =>
request.get('/doctor/infomation', data)
/** /**
* @description 获取当前登录用户信息 * @description 获取当前登录用户信息
* @param realStatus 1-未实名 2-实名中 3--已经实名 4-实名失败 * @param realStatus 1-未实名 2-实名中 3--已经实名 4-实名失败

View File

@ -8,6 +8,7 @@
labelColor="#666" labelColor="#666"
labelSize="24rpx" labelSize="24rpx"
@change="handleChange" @change="handleChange"
:disabled="disabled"
> >
<u-checkbox activeColor="#FF8CA6" name="1"></u-checkbox> <u-checkbox activeColor="#FF8CA6" name="1"></u-checkbox>
<!-- label="我已阅读并同意" --> <!-- label="我已阅读并同意" -->
@ -34,16 +35,18 @@ const prop = defineProps({
type: Boolean, type: Boolean,
default: () => false default: () => false
}, },
checkFunc: { disabled: {
type: Function, type: Boolean,
default: () => () => {} default: () => false
} }
}) })
const checked = ref([false]) const checked = ref([false])
checked.value[0] = prop.agreed ? '1' : ''
const emit = defineEmits(['update:agreed']) const emit = defineEmits(['update:agreed'])
const instance = getCurrentInstance() const instance = getCurrentInstance()
const { $Router } = instance.proxy const { $Router } = instance.proxy
watchEffect(() => {
checked.value[0] = prop.agreed ? '1' : ''
})
const handleAgree = () => { const handleAgree = () => {
$Router.push({ path: '/pages/statement/index' }) $Router.push({ path: '/pages/statement/index' })

View File

@ -6,6 +6,7 @@
:safeAreaInsetBottom="true" :safeAreaInsetBottom="true"
:fixed="true" :fixed="true"
:border="false" :border="false"
v-bind="$attrs"
> >
<block v-for="item in tabbarList" :key="item.path"> <block v-for="item in tabbarList" :key="item.path">
<u-tabbar-item <u-tabbar-item
@ -31,17 +32,12 @@
</template> </template>
<script setup> <script setup>
import store from '@/store/index.js'
import { useRoute } from '@/utils/uni-router'
uni.hideTabBar() uni.hideTabBar()
const route = useRoute()
const instance = getCurrentInstance() const instance = getCurrentInstance()
const { $assets } = instance.proxy const { $assets,$Router,$Route,$store } = instance.proxy
const userStore = store.useUserStore() const tabbarList = ref([])
const userInfo = computed(() => userStore.userInfo) const List = {
simple: [
const tabbarList = ref([
{ {
text: '首页', text: '首页',
icon: '/tabbar/home.png', icon: '/tabbar/home.png',
@ -66,14 +62,42 @@ const tabbarList = ref([
name: 'personal', name: 'personal',
show: true show: true
} }
]) ],
const activeItem = computed(() => { common: [
return route.meta.key {
text: '首页',
icon: '/tabbar/order.png',
activeIcon: '/tabbar/order-sel.png',
path: '/pages/index/order/index',
name: 'order',
show: true
},
{
text: '我的',
icon: '/tabbar/my.png',
activeIcon: '/tabbar/my-sel.png',
path: '/pages/index/personal/index',
name: 'personal',
show: true
}
]
}
const activeItem = ref()
watchEffect(() => {
activeItem.value = $Route.meta.key
const roleName = $store.user.roleName
if(activeItem.value === 'home' && roleName === 'common') {
activeItem.value = 'order'
}
tabbarList.value = List[roleName]
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.u-tabbar-item__icon { .u-tabbar-item__icon {
margin-top: 10rpx;
width: 48rpx; width: 48rpx;
height: 48rpx; height: 48rpx;
object-fit: contain; object-fit: contain;

View File

@ -10,7 +10,8 @@ export const primaryColor = '#FF8CA6'
// 项目基础路径 // 项目基础路径
export const appBasePath = isProduction ? './' : './' export const appBasePath = isProduction ? './' : './'
// 请求地址 // 请求地址
export const requestURL = 'http://192.168.2.155:7788/hospital/app' // export const requestURL = 'http://192.168.2.166:7788/hospital/app'
export const requestURL = 'http://127.0.0.1:7788/hospital/app'
export const requestPath = '' export const requestPath = ''
export const requestFilePath = '/file' export const requestFilePath = '/file'
// 是否开启代理 // 是否开启代理

View File

@ -1,5 +1,5 @@
<template> <template>
<view class="px-24rpx bg-#fff"> <view class="px-24rpx bg-#fff" v-if="userRole === 'simple'">
<u-search <u-search
v-model="searchVal" v-model="searchVal"
shape="square" shape="square"
@ -71,14 +71,17 @@
<u-icon name="arrow-right" width="48rpx" height="48rpx" /> <u-icon name="arrow-right" width="48rpx" height="48rpx" />
</view> </view>
</view> </view>
</view>
<tabbar></tabbar> <tabbar></tabbar>
</view>
<Order v-else />
</template> </template>
<script setup> <script setup>
import { ref, getCurrentInstance } from 'vue' import { ref, getCurrentInstance } from 'vue'
import Order from '../order/index.vue'
const { $Router, $api } = getCurrentInstance().proxy const { $Router, $api,$store } = getCurrentInstance().proxy
const userRole = computed(() => $store.user.userInfo.roleName ?? 'simple')
const searchVal = ref('') const searchVal = ref('')
const swiperList = ref([ const swiperList = ref([
{ {

View File

@ -40,10 +40,10 @@
itemStyle="width: 20%; height: 100rpx;" itemStyle="width: 20%; height: 100rpx;"
></u-tabs> ></u-tabs>
</u-sticky> </u-sticky>
<view class="px-24rpx pt-20rpx">
<view class="h-full">
<template v-for="item in 10" :key="item">
<view <view
v-for="item in 2"
:key="item"
class="min-h-410rpx bg-white rounded-16rpx px-20rpx py-30rpx mb-20rpx shadow-current" class="min-h-410rpx bg-white rounded-16rpx px-20rpx py-30rpx mb-20rpx shadow-current"
> >
<view class="flex-row-between"> <view class="flex-row-between">
@ -93,7 +93,7 @@
> >
</view> </view>
</view> </view>
</view> </template>
</view> </view>
<u-popup <u-popup
class="overflow-hidden" class="overflow-hidden"
@ -136,7 +136,8 @@
</view> </view>
</u-popup> </u-popup>
<button-contact :class="`!bottom-16%`" /> <button-contact :class="`!bottom-16%`" />
<tabbar /> <tabbar :fixed="false" />
</view>
</template> </template>
<script setup> <script setup>

View File

@ -46,7 +46,7 @@
</view> </view>
<view class="relative"> <view class="relative">
<view <view
v-for="(item, index) of listModel" v-for="(item, index) of menuList"
:key="index" :key="index"
class="flex items-center py-4" class="flex items-center py-4"
@click="handleInfo(item)" @click="handleInfo(item)"
@ -118,21 +118,30 @@
<script setup> <script setup>
import defaultAvatar from '@/static/avatar.png' import defaultAvatar from '@/static/avatar.png'
import { onShow } from '@dcloudio/uni-app'
const instance = getCurrentInstance() const instance = getCurrentInstance()
const { $api, $store, $Router, $loading } = instance.proxy const { $api, $store, $Router, $loading } = instance.proxy
const userStore = $store.user const userStore = $store.user
const isLogin = computed(() => !!userStore.token) const isLogin = computed(() => !!$store.user.token)
const userInfo = computed(() => userStore.userInfo) const userInfo = computed(() => $store.user.userInfo)
const showWithdraw = ref(false) const showWithdraw = ref(false)
const amount = ref('') const amount = ref('')
const listModel = [ const list = {
simple: [
{ {
icon: '/personal/person.png', icon: '/personal/shouru.png',
text: '就诊人管理', text: '订单管理',
path: '' path: '/order'
}, },
{
icon: '/personal/qiehuan.png',
text: '成为陪诊师',
path: '/pages/other/switch'
}
],
common: [
{ {
icon: '/personal/shouru.png', icon: '/personal/shouru.png',
text: '收入详情', text: '收入详情',
@ -141,8 +150,16 @@ const listModel = [
{ {
icon: '/personal/qiehuan.png', icon: '/personal/qiehuan.png',
text: '切换身份', text: '切换身份',
path: '/pages/other/switch' path: ''
}, }
]
}
const listConst = [
// {
// icon: '/personal/person.png',
// text: '',
// path: ''
// },
{ {
icon: '/personal/lianxi.png', icon: '/personal/lianxi.png',
text: '联系客服', text: '联系客服',
@ -159,6 +176,12 @@ const listModel = [
path: '/pages/contact/index' path: '/pages/contact/index'
} }
] ]
const menuList = ref([])
watchEffect(() => {
const { roleName = 'simple' } = userInfo.value
menuList.value = [...list[roleName], ...listConst]
})
function handleInfo(item) { function handleInfo(item) {
$Router.push({ $Router.push({
path: item.path, path: item.path,
@ -173,10 +196,12 @@ async function handleLogin() {
$loading(true) $loading(true)
userStore.login().then((user) => { userStore.login().then((user) => {
$loading(false) $loading(false)
!user.id && !user.id
$Router.push({ ? $Router.push({
path: '/pages/other/edit-userinfo' path: '/pages/other/edit-userinfo'
}) })
: userStore.setUserInfo(user)
console.log('🚀 ~ file: index.vue:204 ~ user:', user)
}) })
} else } else
$Router.push({ $Router.push({
@ -188,16 +213,18 @@ async function handleLogin() {
const getUserInfo = async () => { const getUserInfo = async () => {
if (isLogin.value) { if (isLogin.value) {
$loading(true) // $loading(true)
const res = await $api.getUser() const res = await $api.getUser()
if (res.success) { if (res.success) {
$loading(false) // $loading(false)
userStore.setUserInfo(res.wxUser || {}) userStore.setUserInfo(res.wxUser || {})
} else userStore.logout() } else userStore.logout()
} else userStore.removeUserInfo() } else userStore.removeUserInfo()
} }
onShow(() => {
getUserInfo() getUserInfo()
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -35,8 +35,8 @@
shape="square" shape="square"
placement="row" placement="row"
> >
<u-radio :name="0" label="男"></u-radio> <u-radio name="0" label="男"></u-radio>
<u-radio :name="1" label="女" class="ml-50rpx"></u-radio> <u-radio name="1" label="女" class="ml-50rpx"></u-radio>
</u-radio-group> </u-radio-group>
</view> </view>
<view v-else class="w-full text-right u-line-1 pl-2 text-#C0C4CC" <view v-else class="w-full text-right u-line-1 pl-2 text-#C0C4CC"
@ -45,7 +45,7 @@
</u-form-item> </u-form-item>
</u--form> </u--form>
<u--textarea <u--textarea
v-model="model.remark" v-model="model.intro"
placeholder="" placeholder=""
maxlength="300" maxlength="300"
count count
@ -59,26 +59,52 @@
>*</text >*</text
> >
</view> </view>
<view class="flex justify-between mb-32rpx"> <view class="flex justify-between mb-32rpx mt-20rpx">
<view <view
@click="handleChooseImage" @click="handleChooseImage('ren')"
class="relative w-330rpx bg-#f2f2f2 rounded-md px-52rpx pt-30rpx pb-20rpx" class="relative w-330rpx h-250rpx bg-#f2f2f2 rounded-md px-52rpx pt-30rpx pb-20rpx"
> >
<block v-if="!fileList[0]"> <block v-if="!imageObj.ren">
<image class="w-full h-146rpx" :src="$assets('/zheng.png')" /> <image class="w-full h-146rpx" :src="$assets('/zheng.png')" />
<view class="text-24rpx mt-10rpx text-#999 w-full text-center" <view class="text-24rpx mt-10rpx text-#999 w-full text-center"
>上传身份证人像面</view >上传身份证人像面</view
> >
</block> </block>
<view
v-else
class="absolute top-0 left-0 rounded-md overflow-hidden"
>
<u--image
mode="cover"
width="330rpx"
height="250rpx"
:duration="100"
:src="imageObj.ren"
/>
</view>
</view> </view>
<view <view
@click="handleChooseImage" @click="handleChooseImage('fan')"
class="relative w-330rpx bg-#f2f2f2 rounded-md px-52rpx pt-30rpx pb-20rpx" class="relative w-330rpx bg-#f2f2f2 rounded-md px-52rpx pt-30rpx pb-20rpx"
> >
<block v-if="!imageObj.fan">
<image class="w-full h-146rpx" :src="$assets('/fan.png')" /> <image class="w-full h-146rpx" :src="$assets('/fan.png')" />
<view class="text-24rpx mt-10rpx text-#999 w-full text-center" <view class="text-24rpx mt-10rpx text-#999 w-full text-center"
>上传身份证国徽面</view >上传身份证国徽面</view
> >
</block>
<view
v-else
class="absolute top-0 left-0 rounded-md overflow-hidden"
>
<u--image
mode="cover"
width="330rpx"
height="250rpx"
:duration="100"
:src="imageObj.fan"
/>
</view>
</view> </view>
</view> </view>
<text class="text-24rpx text-#999" <text class="text-24rpx text-#999"
@ -90,7 +116,7 @@
<view <view
class="fixed bg-#fff bottom-0 pb-8 left-0 right-0 text-white pt-12rpx border-t-1px border-solid border-#E5E5E5" class="fixed bg-#fff bottom-0 pb-8 left-0 right-0 text-white pt-12rpx border-t-1px border-solid border-#E5E5E5"
><view ><view
@click="handleSubmit" @click="$u.throttle(handleSubmit, 1000)"
class="bg-#FF8CA6 rounded-24rpx w-660rpx h-80rpx text-center leading-80rpx hover:shadow-md mx-auto" class="bg-#FF8CA6 rounded-24rpx w-660rpx h-80rpx text-center leading-80rpx hover:shadow-md mx-auto"
>提交申请</view >提交申请</view
></view ></view
@ -103,14 +129,14 @@
import { chooseImage } from '@uni-helper/uni-promises' import { chooseImage } from '@uni-helper/uni-promises'
const instance = getCurrentInstance() const instance = getCurrentInstance()
const { $api, $toast, $store } = instance.proxy const { $api, $toast, $store, $u, $dialog, $Router, $loading } = instance.proxy
const userInfo = computed(() => $store.user.userInfo) const userInfo = computed(() => $store.user.userInfo)
const fileList = ref([])
const agreed = ref(false) const agreed = ref(false)
const formRef = ref(null) const formRef = ref(null)
const formList = ref([]) const formList = ref([])
const model = ref({}) const model = ref({})
const rules = ref({}) const rules = ref({})
const imageObj = ref({})
// //
const formItems = [ const formItems = [
{ {
@ -131,7 +157,14 @@ const formItems = [
required: true, required: true,
type: 'radio', type: 'radio',
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
message: '请选择性别' message: '请选择性别',
validator: {
validator: (rule, value, callback) => {
return value > -1
},
message: '请选择性别',
trigger: ['change', 'blur']
}
}, },
{ {
label: '年龄', label: '年龄',
@ -140,7 +173,12 @@ const formItems = [
required: true, required: true,
type: 'string', type: 'string',
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
message: '请输入年龄' message: '请输入年龄',
validator: {
validator: (rule, value, callback) => $u.test.digits(value),
message: '年龄必须为数字',
trigger: 'blur'
}
}, },
{ {
label: '手机号', label: '手机号',
@ -149,12 +187,19 @@ const formItems = [
required: true, required: true,
type: 'string', type: 'string',
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
message: '请输入手机号' message: '请输入手机号',
validator: {
validator: (rule, value, callback) => {
return $u.test.mobile(value)
},
message: '手机号码格式有误',
trigger: 'blur'
}
}, },
{ {
label: '微信号', label: '微信号',
placeholder: '请输入微信号', placeholder: '请输入微信号',
key: 'weNumber', key: 'wxNumber',
required: true, required: true,
type: 'string', type: 'string',
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
@ -188,17 +233,34 @@ const formItems = [
// message: '' // message: ''
// } // }
] ]
onMounted(() => {
formRef.value.setRules(rules.value)
})
const init = () => { const init = async () => {
$loading(true)
formItems.forEach((item) => { formItems.forEach((item) => {
const { required, key, keyName, message, trigger } = item const { required, key, keyName, message, trigger, validator } = item
rules.value[item.key] = [{ required, message, trigger }] rules.value[item.key] =
typeof validator === 'object'
? [{ required, message, trigger }, validator]
: [{ required, message, trigger }]
formList.value.push(item) formList.value.push(item)
model.value[key] = userInfo.value[keyName || key] ?? null model.value[key] = userInfo.value[keyName || key] ?? null
}) })
model.value.sex = +userInfo.value.gender
model.value.intro = model.value.intro ?? ''
const res = await $api.doctorInfo()
if (res.success && typeof res.doctor === 'object' && res.doctor) {
Object.assign(model.value, res.doctor)
const images = res.doctor.images.split(',')
imageObj.value.ren = images[0]
imageObj.value.fan = images[1]
}
$loading(false)
} }
const handleChooseImage = async () => { const handleChooseImage = async (key) => {
let filePath = '' let filePath = ''
try { try {
const ret = await chooseImage({ const ret = await chooseImage({
@ -206,7 +268,6 @@ const handleChooseImage = async () => {
}) })
filePath = ret.tempFilePaths[0] filePath = ret.tempFilePaths[0]
} catch (error) { } catch (error) {
console.warn('handleChooseImage.error', error)
return return
} }
if (!filePath) { if (!filePath) {
@ -217,13 +278,51 @@ const handleChooseImage = async () => {
filePath filePath
}) })
if (res.success) { if (res.success) {
console.log('res.data', res) imageObj.value[key] = res.msg
} }
} }
const handleSubmit = () => { const handleSubmit = async () => {
formRef.value?.validate().then(() => { formRef.value?.validate().then(async () => {
if (!imageObj.value.ren) {
$toast('请上传身份证人像面!')
} else if (!imageObj.value.fan) {
$toast('请上传身份证国徽面!')
} else {
if (!agreed.value) {
try {
await $dialog('是否已阅读并同意《服务条款》?', {
showCancelButton: true,
confirmButtonText: '同意',
cancelButtonText: '取消',
confirmColor: '#FF8CA6'
})
agreed.value = true
} catch (error) {
console.log('error', error)
return
}
}
$loading(true)
const images = []
Object.entries(imageObj.value).forEach(([key, value]) => {
images.push(value)
})
model.value.images = images.join(',')
const res = await $api.doctorSave({
...model.value
})
if (res.success) {
$toast('提交成功') $toast('提交成功')
setTimeout(() => {
$Router.push({
path: '/personal'
})
}, 500)
}
$loading(false)
}
}) })
} }

View File

@ -16,7 +16,7 @@ export const useUserStore = defineStore('app-user', {
}, },
getters: { getters: {
userId: state => state.userInfo?.userId, userId: state => state.userInfo?.userId,
avatar: state => state.userInfo?.avatar, roleName: state => state.userInfo?.roleName ?? 'simple',
username: state => state.userInfo?.username, username: state => state.userInfo?.username,
resumed: state => !!state.resumeInfo.id, resumed: state => !!state.resumeInfo.id,
}, },

View File

@ -77,6 +77,7 @@ export default defineConfig({
// }, // },
// }, // },
rollupOptions: { rollupOptions: {
external: ['z-paging'],
// external: ['/wxcomponents'], // external: ['/wxcomponents'],
// output: { // output: {
// manualChunks: undefined, // manualChunks: undefined,