|
|
@@ -1,551 +1,945 @@
|
|
|
<template>
|
|
|
-
|
|
|
- <!-- 我的任务 -->
|
|
|
+ <!-- 访客申请 -->
|
|
|
<view class="container">
|
|
|
- <template v-if="!isLogin">
|
|
|
- <!-- 未登录状态 -->
|
|
|
- <view class="no-login">
|
|
|
- <image src="/static/images/no-login.png" mode="aspectFit" class="no-login-image"></image>
|
|
|
- <text class="no-login-text">登录后查看更多内容</text>
|
|
|
- <button class="login-btn" @click="goToLogin">去登录</button>
|
|
|
+ <!-- 导航栏 -->
|
|
|
+ <custom-navbar title="访客申请" :showBack="true"></custom-navbar>
|
|
|
+
|
|
|
+ <!-- 表单内容 -->
|
|
|
+ <view class="form-container">
|
|
|
+ <!-- 第一块:对接人信息 -->
|
|
|
+ <view class="section">
|
|
|
+ <view class="section-title">
|
|
|
+ <image class="title-icon" src="/static/images/person.png" mode="aspectFit"></image>
|
|
|
+ 对接人信息
|
|
|
+ </view>
|
|
|
+ <view class="mar-b-16">
|
|
|
+ <text class="label">所属部门</text>
|
|
|
+ <view class="select-wrapper">
|
|
|
+ <!-- 调试信息 -->
|
|
|
+ <uni-data-select v-model="formData.departmentId" :localdata="departmentOptions"
|
|
|
+ placeholder="请选择所属部门" @change="onDepartmentSelectChange" :clear="false">
|
|
|
+ </uni-data-select>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="form-item1">
|
|
|
+ <text class="label">员工姓名</text>
|
|
|
+ <view class="select-wrapper">
|
|
|
+ <uni-data-select v-model="formData.employeeId" :localdata="employeeOptions" placeholder="请选择员工"
|
|
|
+ @change="onEmployeeSelectChange" :clear="false">
|
|
|
+ </uni-data-select>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <!-- Visit list -->
|
|
|
- <scroll-view scroll-y class="visit-list" @scrolltolower="onReachBottom">
|
|
|
- <template v-if="taskList.length > 0">
|
|
|
- <view class="visit-item" v-for="(item, index) in taskList" :key="index" @click="goToDetail(item)">
|
|
|
- <view class="visit-date">
|
|
|
- <text class="date-num">{{item.date}}</text>
|
|
|
- <text class="date-month">{{item.year}}</text>
|
|
|
+
|
|
|
+ <!-- 第二块:访问信息 -->
|
|
|
+ <view class="section">
|
|
|
+ <view class="section-title">
|
|
|
+ <image class="title-icon" src="/static/images/calendar.png" mode="aspectFit"></image>
|
|
|
+ 访问信息
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">访问事由</text>
|
|
|
+ <input class="input" v-model="formData.visitReason" placeholder="请输入访问事由"
|
|
|
+ placeholder-style="color: #c0c4cc" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">到访时间</text>
|
|
|
+ <uni-datetime-picker type="datetime" v-model="formData.visitTime" @change="onVisitTimeChange"
|
|
|
+ :clear-icon="false" placeholder="请选择到访时间" format="YYYY-MM-DD HH:mm" :hide-second="true">
|
|
|
+ <view class="input-wrapper">
|
|
|
+ <text class="placeholder" v-if="!formData.visitTime">请选择到访时间</text>
|
|
|
+ <text v-else>{{ formData.visitTime }}</text>
|
|
|
+ <uni-icons type="calendar" size="16" color="#c0c4cc"></uni-icons>
|
|
|
</view>
|
|
|
- <view class="visit-content">
|
|
|
- <view class="visit-header">
|
|
|
- <view class="visitor-info">
|
|
|
- <text class="visitor-label">对接人 </text>
|
|
|
- <text class="visitor-name">{{item.employeeName}}</text>
|
|
|
- </view>
|
|
|
- <text class="visit-status" :class="getStatusClass(item.status)">{{item.status}}</text>
|
|
|
- </view>
|
|
|
- <view class="visit-desc">{{item.visitReason}}</view>
|
|
|
- <view class="visit-time">
|
|
|
- <u-icon name="clock" size="12" color="#999"></u-icon>
|
|
|
- <text>{{item.time}}</text>
|
|
|
- </view>
|
|
|
+ </uni-datetime-picker>
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">访客姓名</text>
|
|
|
+ <input class="input" v-model="formData.visitorName" placeholder="请输入访客姓名"
|
|
|
+ placeholder-style="color: #c0c4cc" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">访客单位</text>
|
|
|
+ <input class="input" v-model="formData.visitorCompany" placeholder="请输入访客单位"
|
|
|
+ placeholder-style="color: #c0c4cc" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">手机号</text>
|
|
|
+ <input class="input" v-model="formData.visitorPhone" placeholder="请输入手机号"
|
|
|
+ placeholder-style="color: #c0c4cc" type="number" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 第三块:随行人员 -->
|
|
|
+ <view class="section">
|
|
|
+ <view class="section-title">随行人员</view>
|
|
|
+ <view class="accompany-list">
|
|
|
+ <view class="accompany-item" v-for="(item, index) in formData.accompanyPersons" :key="index">
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">随行人员</text>
|
|
|
+ <input class="input" v-model="item.name" placeholder="请输入随行人员姓名"
|
|
|
+ placeholder-style="color: #c0c4cc" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">手机号</text>
|
|
|
+ <input class="input" v-model="item.phone" placeholder="请输入手机号"
|
|
|
+ placeholder-style="color: #c0c4cc" type="number" />
|
|
|
+ </view>
|
|
|
+ <view class="delete-btn" v-if="formData.accompanyPersons.length > 1"
|
|
|
+ @click="removeAccompany(index)">
|
|
|
+ <uni-icons type="trash" size="18" color="#ff4757"></uni-icons>
|
|
|
</view>
|
|
|
</view>
|
|
|
- <!-- Loading more -->
|
|
|
- <u-loadmore :status="loadMoreStatus" />
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <!-- 暂无数据 -->
|
|
|
- <view class="flex-items-plus">
|
|
|
- <image src="../../static/images/empty.png" class="empty "></image>
|
|
|
- </view>
|
|
|
- <view class="font28 font-gray flex-items-plus">
|
|
|
- 数据为空
|
|
|
+ </view>
|
|
|
+ <view class="add-accompany-btn" @click="addAccompany">
|
|
|
+ <uni-icons type="plus" size="16" color="#007aff"></uni-icons>
|
|
|
+ <text>添加随行人员</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 第四块:使用车辆 -->
|
|
|
+ <view class="section">
|
|
|
+ <view class="vehicle-header">
|
|
|
+ <view class="section-title">
|
|
|
+ <image class="title-icon" src="/static/images/cart.png" mode="aspectFit"></image>
|
|
|
+ 使用车辆
|
|
|
</view>
|
|
|
- </template>
|
|
|
- </scroll-view>
|
|
|
+ <switch :checked="formData.useVehicle" @change="onVehicleChange" color="#007aff" />
|
|
|
+ </view>
|
|
|
|
|
|
- <!-- Floating button -->
|
|
|
- <view class="floating-button" @click="showApplyPopup">
|
|
|
- <text class="floating-text">申请<br>访问</text>
|
|
|
- </view>
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- Application method popup -->
|
|
|
- <uni-popup ref="popup" type="center" border-radius="16rpx">
|
|
|
- <view class="popup-content">
|
|
|
- <view class="popup-title">
|
|
|
- 选择申请方式
|
|
|
- <text class="close-icon" @click="closePopup">×</text>
|
|
|
+ <view v-if="formData.useVehicle" class="vehicle-content">
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">接客时间</text>
|
|
|
+ <uni-datetime-picker type="datetime" v-model="formData.pickupTime" @change="onPickupTimeChange"
|
|
|
+ :clear-icon="false" placeholder="请选择接客时间" format="YYYY-MM-DD HH:mm" :hide-second="true">
|
|
|
+ <view class="input-wrapper">
|
|
|
+ <text class="placeholder" v-if="!formData.pickupTime">请选择接客时间</text>
|
|
|
+ <text v-else>{{ formData.pickupTime }}</text>
|
|
|
+ <uni-icons type="calendar" size="16" color="#c0c4cc"></uni-icons>
|
|
|
+ </view>
|
|
|
+ </uni-datetime-picker>
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">接客地点</text>
|
|
|
+ <input class="input" v-model="formData.pickupLocation" placeholder="请输入接客地点"
|
|
|
+ placeholder-style="color: #c0c4cc" />
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- <view class="apply-methods">
|
|
|
- <view class="method-item" @click="handleApply('self')">
|
|
|
- <view class="method-icon green-bg">
|
|
|
- <image src="/static/images/apply.png" mode="aspectFit"></image>
|
|
|
- </view>
|
|
|
- <text class="font-bold">发起申请</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 提交按钮 -->
|
|
|
+ <view class="submit-container">
|
|
|
+ <button class="submit-btn" @click="submitForm">提交</button>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 提交成功弹框 -->
|
|
|
+ <uni-popup ref="successPopup" type="center" :mask-click="false">
|
|
|
+ <view class="success-popup">
|
|
|
+ <view class="popup-content">
|
|
|
+ <view class="success-icon">
|
|
|
+ <uni-icons type="checkmarkempty" size="60" color="#52c41a"></uni-icons>
|
|
|
</view>
|
|
|
- <view class="method-item" @click="handleApply('proxy')">
|
|
|
- <view class="method-icon orange-bg">
|
|
|
- <image src="/static/images/behalf.png" mode="aspectFit"></image>
|
|
|
+ <view class="popup-title">申请提交成功</view>
|
|
|
+ <view class="popup-message">您的申请已成功提交,请关注公众号即时查询审核结果</view>
|
|
|
+ <view class="popup-buttons">
|
|
|
+ <button class="cancel-btn" @click="closeSuccessPopup">取消</button>
|
|
|
+ <button class="follow-btn" @click="showQRCode">关注</button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </uni-popup>
|
|
|
+
|
|
|
+ <!-- 二维码弹框 -->
|
|
|
+ <uni-popup ref="qrcodePopup" type="center" :mask-click="false">
|
|
|
+ <view class="qrcode-popup">
|
|
|
+ <view class="qrcode-content">
|
|
|
+ <view class="qrcode-title">扫描二维码关注公众号</view>
|
|
|
+ <view class="qrcode-image" @click="previewQRCode">
|
|
|
+ <image src="/static/images/qrcode.png" mode="aspectFit"></image>
|
|
|
+ <view class="preview-tip">
|
|
|
+ <uni-icons type="search" size="16" color="#fff"></uni-icons>
|
|
|
+ <text>点击查看大图</text>
|
|
|
</view>
|
|
|
- <text class="font-bold">代客申请</text>
|
|
|
</view>
|
|
|
+ <view class="qrcode-tip">扫描上方二维码,关注公众号获取审核结果</view>
|
|
|
+ <button class="qrcode-close-btn" @click="closeQRCode">我知道了</button>
|
|
|
</view>
|
|
|
</view>
|
|
|
</uni-popup>
|
|
|
+
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+ import user from '../../store/modules/user';
|
|
|
import {
|
|
|
- orderList,
|
|
|
- userLogin
|
|
|
+
|
|
|
+ getDept,
|
|
|
+ selectUser,
|
|
|
+ addVisit
|
|
|
} from '@/config/api.js';
|
|
|
- import {
|
|
|
- mapGetters
|
|
|
- } from 'vuex';
|
|
|
- import {
|
|
|
- shareImg
|
|
|
- } from '@/common/config.js'
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
- taskList: [],
|
|
|
- loadMoreStatus: 'loadmore', // loadmore, loading, nomore
|
|
|
- params: {
|
|
|
- current: 1,
|
|
|
- size: 10,
|
|
|
+ type: '', // 从上一页传递过来的参数
|
|
|
+ tabbarHeight: 50, // tabbar高度,默认50px
|
|
|
+ user: null, // 用户信息
|
|
|
+ formData: {
|
|
|
+ departmentId: '',
|
|
|
+ department: '',
|
|
|
+ employeeId: '',
|
|
|
+ employeeName: '',
|
|
|
+ visitReason: '',
|
|
|
+ visitTime: '',
|
|
|
+ visitorName: '',
|
|
|
+ visitorCompany: '',
|
|
|
+ visitorPhone: '',
|
|
|
+ accompanyPersons: [{
|
|
|
+ name: '',
|
|
|
+ phone: ''
|
|
|
+ }],
|
|
|
+ useVehicle: false,
|
|
|
+ pickupTime: '',
|
|
|
+ pickupLocation: ''
|
|
|
},
|
|
|
- hasMore: true
|
|
|
+ // 部门数据
|
|
|
+ departments: [],
|
|
|
+ // 部门选项(格式化为uni-data-select所需格式)
|
|
|
+ departmentOptions: [],
|
|
|
+ // 员工选项
|
|
|
+ employeeOptions: [],
|
|
|
}
|
|
|
},
|
|
|
- computed: {
|
|
|
- ...mapGetters(['isLogin'])
|
|
|
- },
|
|
|
onLoad(options) {
|
|
|
- this.getList();
|
|
|
- },
|
|
|
- // 微信小程序分享配置
|
|
|
- onShareAppMessage() {
|
|
|
- return {
|
|
|
- title: `邀请您加入知己访客`,
|
|
|
- path: `/pages/index/index`,
|
|
|
- imageUrl: shareImg // 分享图片,需要添加
|
|
|
+ console.log(uni.getStorageSync("user"), "usususuus")
|
|
|
+ // 获取传递过来的参数
|
|
|
+ if (options.type) {
|
|
|
+ this.type = options.type;
|
|
|
}
|
|
|
+ // 获取用户信息
|
|
|
+ this.user = uni.getStorageSync("user")
|
|
|
+ this.getTabbarHeight()
|
|
|
+ this.getDeptList()
|
|
|
},
|
|
|
- onShareTimeline(res) {
|
|
|
- let that = this;
|
|
|
- let shareInfo = store.state.vuex_shareInfo;
|
|
|
- let query = shareInfo.query;
|
|
|
- //携带当前页面资源ID参数
|
|
|
- let currentPage = getCurrentPages()[getCurrentPages().length - 1];
|
|
|
- let options = currentPage.options;
|
|
|
- if (JSON.stringify(options) != '{}' && options.id) {
|
|
|
- query += `&id=${options.id}`;
|
|
|
- }
|
|
|
+ onReady() {
|
|
|
+ // 页面渲染完成后再次获取,确保准确
|
|
|
+ this.getTabbarHeight()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 获取tabbar高度
|
|
|
+ getTabbarHeight() {
|
|
|
+ // 获取菜单按钮信息,用于计算真实的可用高度
|
|
|
+ const systemInfo = uni.getSystemInfoSync()
|
|
|
+
|
|
|
+ // 在微信小程序中,使用 windowHeight 和 screenHeight 的差值
|
|
|
+ // windowHeight 是不包含 tabbar 的可用高度
|
|
|
+ const windowHeight = systemInfo.windowHeight
|
|
|
+ const screenHeight = systemInfo.screenHeight
|
|
|
+
|
|
|
+ // 微信小程序 tabbar 高度通常是 50px,但在不同设备可能不同
|
|
|
+ // 直接使用差值
|
|
|
+ let tabbarHeight = screenHeight - windowHeight
|
|
|
+
|
|
|
+ console.log('系统信息:', {
|
|
|
+ screenHeight,
|
|
|
+ windowHeight,
|
|
|
+ 计算的tabbar高度: tabbarHeight,
|
|
|
+ safeAreaBottom: systemInfo.safeAreaInsets?.bottom || systemInfo.safeArea?.bottom || 0
|
|
|
+ })
|
|
|
|
|
|
- return {
|
|
|
- title: shareInfo.title,
|
|
|
- query: query,
|
|
|
- imageUrl: shareImg,
|
|
|
- success(res) {
|
|
|
- uni.showToast({
|
|
|
- title: '分享成功'
|
|
|
+ // 在小程序中通常是 50-80 之间
|
|
|
+ // 如果是 H5,差值会包含地址栏等,会更大
|
|
|
+ // #ifdef MP-WEIXIN
|
|
|
+ if (tabbarHeight < 30 || tabbarHeight > 100) {
|
|
|
+ tabbarHeight = 50 // 微信小程序默认 50px
|
|
|
+ }
|
|
|
+ // #endif
|
|
|
+
|
|
|
+ // #ifdef H5
|
|
|
+ tabbarHeight = 50 // H5 固定使用 50px
|
|
|
+ // #endif
|
|
|
+
|
|
|
+ this.tabbarHeight = tabbarHeight
|
|
|
+ },
|
|
|
+
|
|
|
+ async getDeptList() {
|
|
|
+ console.log("获取DEPT")
|
|
|
+ try {
|
|
|
+ const res = await getDept({
|
|
|
+ parentId: 100
|
|
|
})
|
|
|
- },
|
|
|
- fail(res) {
|
|
|
+ console.log("部门API返回数据:", res)
|
|
|
+ this.departments = res.data
|
|
|
+ // 格式化部门数据为uni-data-select所需格式
|
|
|
+ this.departmentOptions = res.data.map(item => ({
|
|
|
+ value: item.dept_id,
|
|
|
+ text: item.dept_name
|
|
|
+ }))
|
|
|
+ console.log("格式化后的部门选项:", this.departmentOptions)
|
|
|
+
|
|
|
+ // 添加延时确保数据已经设置
|
|
|
+ this.$nextTick(() => {
|
|
|
+ console.log("nextTick后的部门选项:", this.departmentOptions)
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ console.error("获取部门列表失败:", error)
|
|
|
uni.showToast({
|
|
|
- title: '分享失败',
|
|
|
+ title: '获取部门列表失败',
|
|
|
icon: 'none'
|
|
|
})
|
|
|
- },
|
|
|
- }
|
|
|
- },
|
|
|
- onShow() {
|
|
|
- // #ifdef H5
|
|
|
- this.login()
|
|
|
- // #endif
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
- },
|
|
|
|
|
|
|
|
|
- onPullDownRefresh() {
|
|
|
- this.refresh()
|
|
|
- uni.stopPullDownRefresh();
|
|
|
- },
|
|
|
+ // 部门选择改变
|
|
|
+ async onDepartmentSelectChange(value) {
|
|
|
+ console.log("选择的部门ID:", value)
|
|
|
+ this.formData.departmentId = value
|
|
|
+ // 找到选中的部门信息
|
|
|
+ const selectedDept = this.departments.find(dept => dept.dept_id === value)
|
|
|
+ if (selectedDept) {
|
|
|
+ this.formData.department = selectedDept.dept_name
|
|
|
+ // 根据部门ID获取员工列表
|
|
|
+ try {
|
|
|
+ const userRes = await selectUser({
|
|
|
+ deptId: value
|
|
|
+ })
|
|
|
+ console.log("员工列表:", userRes)
|
|
|
+ // 格式化员工数据为uni-data-select所需格式
|
|
|
+ if (userRes && userRes.rows) {
|
|
|
+ this.employeeOptions = userRes.rows.map(item => ({
|
|
|
+ value: item.user_id,
|
|
|
+ text: item.nick_name
|
|
|
+ }))
|
|
|
+ console.log("格式化后的员工选项:", this.employeeOptions)
|
|
|
+ } else if (userRes && userRes.data && userRes.data.rows) {
|
|
|
+ // 备用路径,以防数据结构不同
|
|
|
+ this.employeeOptions = userRes.data.rows.map(item => ({
|
|
|
+ value: item.user_id,
|
|
|
+ text: item.nick_name
|
|
|
+ }))
|
|
|
+ console.log("格式化后的员工选项(备用路径):", this.employeeOptions)
|
|
|
+ }
|
|
|
+ // 清空之前选择的员工
|
|
|
+ this.formData.employeeId = ''
|
|
|
+ this.formData.employeeName = ''
|
|
|
+ } catch (error) {
|
|
|
+ console.error("获取员工列表失败:", error)
|
|
|
+ uni.showToast({
|
|
|
+ title: '获取员工列表失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
+ // 员工选择改变
|
|
|
+ onEmployeeSelectChange(value) {
|
|
|
+ console.log("选择的员工ID:", value)
|
|
|
+ this.formData.employeeId = value
|
|
|
+ // 根据employeeOptions找到对应的员工名称
|
|
|
+ const selectedEmployee = this.employeeOptions.find(emp => emp.value === value)
|
|
|
+ if (selectedEmployee) {
|
|
|
+ this.formData.employeeName = selectedEmployee.text
|
|
|
+ console.log("选择的员工名称:", selectedEmployee.text)
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
- methods: {
|
|
|
|
|
|
- // Refresh list
|
|
|
- refresh() {
|
|
|
- this.taskList = []
|
|
|
- this.params.current = 1
|
|
|
- this.hasMore = true
|
|
|
- this.loadMoreStatus = 'loadmore'
|
|
|
- this.getList()
|
|
|
- },
|
|
|
|
|
|
- // Handle reaching bottom of scroll
|
|
|
- onReachBottom() {
|
|
|
- if (!this.hasMore || this.loadMoreStatus === 'loading') return
|
|
|
+ // 到访时间改变
|
|
|
+ onVisitTimeChange(e) {
|
|
|
+ this.formData.visitTime = e;
|
|
|
+ },
|
|
|
|
|
|
- this.params.current++
|
|
|
- this.getList(true)
|
|
|
+ // 接客时间改变
|
|
|
+ onPickupTimeChange(e) {
|
|
|
+ this.formData.pickupTime = e;
|
|
|
},
|
|
|
|
|
|
- // Show apply popup
|
|
|
- showApplyPopup() {
|
|
|
- console.log('显示申请弹窗');
|
|
|
- this.$refs.popup.open()
|
|
|
+ // 获取当前日期时间
|
|
|
+ getCurrentDatetime() {
|
|
|
+ const now = new Date();
|
|
|
+ const year = now.getFullYear();
|
|
|
+ const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
|
+ const day = String(now.getDate()).padStart(2, '0');
|
|
|
+ const hour = String(now.getHours()).padStart(2, '0');
|
|
|
+ const minute = String(now.getMinutes()).padStart(2, '0');
|
|
|
+ return `${year}-${month}-${day} ${hour}:${minute}`;
|
|
|
},
|
|
|
|
|
|
- // Close popup
|
|
|
- closePopup() {
|
|
|
- this.$refs.popup.close()
|
|
|
+ // 添加随行人员
|
|
|
+ addAccompany() {
|
|
|
+ this.formData.accompanyPersons.push({
|
|
|
+ name: '',
|
|
|
+ phone: ''
|
|
|
+ });
|
|
|
},
|
|
|
|
|
|
- // Handle apply method selection
|
|
|
- handleApply(type) {
|
|
|
- if (!this.isLogin) {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pagesA/public/login'
|
|
|
- });
|
|
|
- return
|
|
|
- }
|
|
|
- console.log('选择申请方式:', type);
|
|
|
- this.$refs.popup.close()
|
|
|
- if (type === 'self') {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pagesA/task/edit?type=1'
|
|
|
- })
|
|
|
- } else {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pagesA/task/edit?type=2'
|
|
|
- })
|
|
|
+ // 删除随行人员
|
|
|
+ removeAccompany(index) {
|
|
|
+ if (this.formData.accompanyPersons.length > 1) {
|
|
|
+ this.formData.accompanyPersons.splice(index, 1);
|
|
|
}
|
|
|
},
|
|
|
|
|
|
- // Login method
|
|
|
- login() {
|
|
|
- let params = {
|
|
|
- username: "USER082927",
|
|
|
- grant_type: "web",
|
|
|
- memberId: "1957060037088083973"
|
|
|
+ // 车辆开关改变
|
|
|
+ onVehicleChange(e) {
|
|
|
+ this.formData.useVehicle = e.detail.value;
|
|
|
+ if (!this.formData.useVehicle) {
|
|
|
+ // 关闭车辆使用时清空相关信息
|
|
|
+ this.formData.pickupTime = '';
|
|
|
+ this.formData.pickupLocation = '';
|
|
|
}
|
|
|
- userLogin(params).then((loginData) => {
|
|
|
- uni.setStorageSync('access_token', loginData.access_token);
|
|
|
- uni.setStorageSync('refresh_token', loginData.refresh_token);
|
|
|
- uni.setStorageSync('user', loginData);
|
|
|
+ },
|
|
|
|
|
|
- this.$store.commit('isLogin', true);
|
|
|
- this.$store.commit('refresh_token', loginData.refresh_token);
|
|
|
- })
|
|
|
+
|
|
|
+ // 手机号格式校验
|
|
|
+ validatePhone(phone) {
|
|
|
+ const phoneRegex = /^1[3-9]\d{9}$/;
|
|
|
+ return phoneRegex.test(phone);
|
|
|
},
|
|
|
|
|
|
- // Get visit list with mock data
|
|
|
- getList(loadMore = false) {
|
|
|
- if (!loadMore) {
|
|
|
- uni.showLoading({
|
|
|
- title: '加载中...'
|
|
|
+ // 表单验证
|
|
|
+ validateForm() {
|
|
|
+ if (!this.formData.department) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请选择所属部门',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!this.formData.employeeName) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入员工姓名',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!this.formData.visitReason) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入访问事由',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!this.formData.visitTime) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请选择到访时间',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!this.formData.visitorName) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入访客姓名',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!this.formData.visitorCompany) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入访客单位',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!this.formData.visitorPhone) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入手机号',
|
|
|
+ icon: 'none'
|
|
|
});
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- this.loadMoreStatus = 'loading'
|
|
|
-
|
|
|
- // 模拟接口延迟
|
|
|
- setTimeout(() => {
|
|
|
- // 模拟数据
|
|
|
- const mockData = Array(10).fill(0).map((_, index) => {
|
|
|
- const currentIndex = (this.params.current - 1) * 10 + index;
|
|
|
- const date = new Date();
|
|
|
- date.setDate(date.getDate() - currentIndex); // 每条数据日期递减
|
|
|
-
|
|
|
- const statusList = ['待访问', '待审核', '已拒绝'];
|
|
|
- const descList = [
|
|
|
- '我是访问事由我是访问事由我是访问事由...',
|
|
|
- '需要进行业务对接商谈...',
|
|
|
- '产品展示与技术交流...',
|
|
|
- '项目合作洽谈...'
|
|
|
- ];
|
|
|
-
|
|
|
- return {
|
|
|
- id: currentIndex,
|
|
|
- employeeName: `范海洋${currentIndex + 1}`,
|
|
|
- createTime: date,
|
|
|
- status: statusList[Math.floor(Math.random() * statusList.length)],
|
|
|
- visitReason: descList[Math.floor(Math.random() * descList.length)]
|
|
|
- };
|
|
|
+ // 校验访客手机号格式
|
|
|
+ if (!this.validatePhone(this.formData.visitorPhone)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入正确的手机号格式',
|
|
|
+ icon: 'none'
|
|
|
});
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- const list = mockData.map(item => ({
|
|
|
- ...item,
|
|
|
- date: this.$u.timeFormat(item.createTime, 'DD'),
|
|
|
- year: this.$u.timeFormat(item.createTime, 'YYYY/MM'),
|
|
|
- time: this.$u.timeFormat(item.createTime, 'hh:mm')
|
|
|
- }));
|
|
|
-
|
|
|
- if (loadMore) {
|
|
|
- this.taskList = [...this.taskList, ...list];
|
|
|
- } else {
|
|
|
- this.taskList = list;
|
|
|
+ // 验证随行人员信息
|
|
|
+ for (let i = 0; i < this.formData.accompanyPersons.length; i++) {
|
|
|
+ const person = this.formData.accompanyPersons[i];
|
|
|
+ if (person.name && !person.phone) {
|
|
|
+ uni.showToast({
|
|
|
+ title: `请输入第${i + 1}个随行人员的手机号`,
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
}
|
|
|
+ if (!person.name && person.phone) {
|
|
|
+ uni.showToast({
|
|
|
+ title: `请输入第${i + 1}个随行人员的姓名`,
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 校验随行人员手机号格式
|
|
|
+ if (person.phone && !this.validatePhone(person.phone)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: `第${i + 1}个随行人员手机号格式不正确`,
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 模拟总共有5页数据
|
|
|
- this.hasMore = this.params.current < 5;
|
|
|
- this.loadMoreStatus = this.hasMore ? 'loadmore' : 'nomore';
|
|
|
-
|
|
|
- if (!loadMore) {
|
|
|
- uni.hideLoading();
|
|
|
+ // 验证车辆使用信息
|
|
|
+ if (this.formData.useVehicle) {
|
|
|
+ if (!this.formData.pickupTime) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请选择接客时间',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
}
|
|
|
- }, 500); // 增加500ms延迟模拟网络请求
|
|
|
+ if (!this.formData.pickupLocation) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请选择接客地点',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
},
|
|
|
|
|
|
- // Get status class for styling
|
|
|
- getStatusClass(status) {
|
|
|
- const statusMap = {
|
|
|
- '待访问': 'status-pending-visit',
|
|
|
- '待审核': 'status-pending-review',
|
|
|
- '已拒绝': 'status-rejected'
|
|
|
+ // 提交表单
|
|
|
+ async submitForm() {
|
|
|
+ if (!this.validateForm()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 过滤空的随行人员
|
|
|
+ const validAccompanyPersons = this.formData.accompanyPersons.filter(person =>
|
|
|
+ person.name && person.phone
|
|
|
+ );
|
|
|
+
|
|
|
+ // 构建提交数据
|
|
|
+ const submitData = {
|
|
|
+ visitDate: this.formData.visitTime, // 访问时间
|
|
|
+ // userId: this.user?.id || '', // 员工id
|
|
|
+ empName: this.formData.employeeName, // 访问部门人(员工姓名)
|
|
|
+ visDept: this.formData.visitorCompany, // 访客单位
|
|
|
+ visitPerson: this.formData.visitorName, // 访客姓名
|
|
|
+ visitorTel: this.formData.visitorPhone, // 访客手机
|
|
|
+ visitorNum: (validAccompanyPersons.length + 1).toString(), // 访问人数(访客+随行人员)
|
|
|
+ visitReson: this.formData.visitReason, // 访问事由
|
|
|
+ accPerson: JSON.stringify(validAccompanyPersons) // 随行人员转为JSON字符串
|
|
|
+ };
|
|
|
+
|
|
|
+ console.log('提交数据:', submitData);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 调用后端接口提交数据
|
|
|
+ const response = await addVisit(submitData);
|
|
|
+ console.log('提交成功:', response);
|
|
|
+
|
|
|
+ // 显示提交成功弹框
|
|
|
+ this.$refs.successPopup.open();
|
|
|
+ } catch (error) {
|
|
|
+ console.error('提交失败:', error);
|
|
|
+ uni.showToast({
|
|
|
+ title: '提交失败,请重试',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
}
|
|
|
- return statusMap[status] || 'status-default'
|
|
|
},
|
|
|
|
|
|
- // 跳转到详情页面
|
|
|
- goToDetail(item) {
|
|
|
- uni.navigateTo({
|
|
|
- url: `/pagesA/task/detail?id=${item.id}&status=${item.status}`
|
|
|
- });
|
|
|
+ // 关闭成功弹框
|
|
|
+ closeSuccessPopup() {
|
|
|
+ this.$refs.successPopup.close();
|
|
|
+ // 返回上一页
|
|
|
+ uni.navigateBack();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 显示二维码
|
|
|
+ showQRCode() {
|
|
|
+ this.$refs.successPopup.close();
|
|
|
+ this.$refs.qrcodePopup.open();
|
|
|
},
|
|
|
|
|
|
- // 跳转到登录页面
|
|
|
- goToLogin() {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pagesA/public/login'
|
|
|
+ // 关闭二维码弹框
|
|
|
+ closeQRCode() {
|
|
|
+ this.$refs.qrcodePopup.close();
|
|
|
+ // 返回上一页
|
|
|
+ uni.navigateBack();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 预览二维码
|
|
|
+ previewQRCode() {
|
|
|
+ uni.previewImage({
|
|
|
+ urls: ['/static/images/qrcode.png'],
|
|
|
+ current: 0
|
|
|
});
|
|
|
},
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.container {
|
|
|
- min-height: 100vh;
|
|
|
background-color: #f5f5f5;
|
|
|
-
|
|
|
- .no-login {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- padding-top: 30vh;
|
|
|
-
|
|
|
- .no-login-image {
|
|
|
- width: 240rpx;
|
|
|
- height: 240rpx;
|
|
|
- margin-bottom: 40rpx;
|
|
|
- }
|
|
|
-
|
|
|
- .no-login-text {
|
|
|
- font-size: 32rpx;
|
|
|
- color: #999;
|
|
|
- margin-bottom: 60rpx;
|
|
|
- }
|
|
|
-
|
|
|
- .login-btn {
|
|
|
- width: 320rpx;
|
|
|
- height: 88rpx;
|
|
|
- background: #FF6B00;
|
|
|
- border-radius: 44rpx;
|
|
|
- color: #fff;
|
|
|
- font-size: 32rpx;
|
|
|
- font-weight: 500;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- }
|
|
|
- }
|
|
|
+ min-height: 100vh;
|
|
|
}
|
|
|
|
|
|
- .visit-list {
|
|
|
- height: 100vh;
|
|
|
+ .form-container {
|
|
|
+ padding: 20rpx;
|
|
|
}
|
|
|
|
|
|
- .visit-item {
|
|
|
+ .section {
|
|
|
background-color: #fff;
|
|
|
- margin: 16rpx 20rpx;
|
|
|
- border-radius: 16rpx;
|
|
|
- padding: 24rpx;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .section-title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
display: flex;
|
|
|
- align-items: flex-start;
|
|
|
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
|
|
+ align-items: center;
|
|
|
}
|
|
|
|
|
|
- .visit-date {
|
|
|
+ .title-icon {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ margin-right: 15rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-item {
|
|
|
display: flex;
|
|
|
- flex-direction: column;
|
|
|
align-items: center;
|
|
|
- margin-right: 24rpx;
|
|
|
- min-width: 80rpx;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+ position: relative;
|
|
|
|
|
|
- .date-num {
|
|
|
- font-size: 48rpx;
|
|
|
- font-weight: bold;
|
|
|
- color: #333;
|
|
|
- line-height: 1;
|
|
|
+ &:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- .date-month {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #999;
|
|
|
- margin-top: 4rpx;
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+ .label {
|
|
|
+ width: 160rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
|
|
|
|
- .visit-content {
|
|
|
+ .input {
|
|
|
flex: 1;
|
|
|
+ height: 70rpx;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ background-color: #f8f8f8;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
|
|
|
- .visit-header {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 12rpx;
|
|
|
-
|
|
|
- .visitor-info {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
+ .input-wrapper {
|
|
|
+ flex: 1;
|
|
|
+ height: 70rpx;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ background-color: #f8f8f8;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
|
|
|
- .visitor-label {
|
|
|
- margin-right: 10rpx;
|
|
|
- font-size: 32rpx;
|
|
|
- color: #333;
|
|
|
- font-weight: normal;
|
|
|
- }
|
|
|
+ .placeholder {
|
|
|
+ color: #c0c4cc;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
|
|
|
- .visitor-name {
|
|
|
- font-size: 36rpx;
|
|
|
- color: #333;
|
|
|
- font-weight: bold;
|
|
|
- }
|
|
|
- }
|
|
|
+ .select-wrapper {
|
|
|
+ flex: 1;
|
|
|
|
|
|
- .visit-status {
|
|
|
- font-size: 28rpx;
|
|
|
- padding: 4rpx 12rpx;
|
|
|
- border-radius: 12rpx;
|
|
|
+ ::v-deep .uni-stat__select {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
|
|
|
- &.status-pending-visit {
|
|
|
- color: #4CAF50;
|
|
|
- background-color: rgba(76, 175, 80, 0.1);
|
|
|
- }
|
|
|
+ ::v-deep .uni-stat-box {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
|
|
|
- &.status-pending-review {
|
|
|
- color: #2196F3;
|
|
|
- background-color: rgba(33, 150, 243, 0.1);
|
|
|
- }
|
|
|
+ ::v-deep .uni-select {
|
|
|
+ width: 100%;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
|
|
|
- &.status-rejected {
|
|
|
- color: #F44336;
|
|
|
- background-color: rgba(244, 67, 54, 0.1);
|
|
|
- }
|
|
|
- }
|
|
|
+ ::v-deep .uni-select__input-box {
|
|
|
+ height: 70rpx;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ background-color: #f8f8f8;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ border: none;
|
|
|
}
|
|
|
|
|
|
- .visit-desc {
|
|
|
- color: #666;
|
|
|
+ ::v-deep .uni-select__input-text {
|
|
|
font-size: 28rpx;
|
|
|
- line-height: 1.4;
|
|
|
- margin-bottom: 12rpx;
|
|
|
+ color: #333;
|
|
|
}
|
|
|
|
|
|
- .visit-time {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 8rpx;
|
|
|
+ ::v-deep .uni-select__input-placeholder {
|
|
|
+ color: #c0c4cc;
|
|
|
+ }
|
|
|
|
|
|
- text {
|
|
|
- color: #999;
|
|
|
- font-size: 24rpx;
|
|
|
+ ::v-deep .uni-select__selector {
|
|
|
+ max-height: 400rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .accompany-list {
|
|
|
+ .accompany-item {
|
|
|
+ position: relative;
|
|
|
+ padding: 20rpx;
|
|
|
+ background-color: #f8f8f8;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .floating-button {
|
|
|
- position: fixed;
|
|
|
- bottom: 120rpx;
|
|
|
- right: 40rpx;
|
|
|
- width: 120rpx;
|
|
|
- height: 120rpx;
|
|
|
- background-color: #FF6B00;
|
|
|
- border-radius: 16rpx;
|
|
|
+ .delete-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: 10rpx;
|
|
|
+ right: 10rpx;
|
|
|
+ width: 60rpx;
|
|
|
+ height: 60rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- box-shadow: 0 8rpx 20rpx rgba(255, 107, 0, 0.3);
|
|
|
- z-index: 999;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 50%;
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
|
|
+ }
|
|
|
|
|
|
- .floating-text {
|
|
|
- color: #fff;
|
|
|
- font-size: 28rpx;
|
|
|
- text-align: center;
|
|
|
- line-height: 1.2;
|
|
|
+ .add-accompany-btn {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ height: 80rpx;
|
|
|
+ background-color: #f8f9fa;
|
|
|
+ border: 2rpx dashed #c0c4cc;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 28rpx;
|
|
|
+
|
|
|
+ text {
|
|
|
+ margin-left: 10rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .popup-content {
|
|
|
- width: 600rpx;
|
|
|
- padding: 70rpx 40rpx;
|
|
|
+ .vehicle-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .section-title {
|
|
|
+ flex: 1;
|
|
|
+ margin-bottom: 0;
|
|
|
+ margin-left: 15rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .vehicle-content {
|
|
|
+ padding-top: 20rpx;
|
|
|
+ border-top: 1rpx solid #eee;
|
|
|
+ }
|
|
|
+
|
|
|
+ .submit-container {
|
|
|
+ padding: 20rpx;
|
|
|
+ background-color: #fff;
|
|
|
+ margin-top: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .submit-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 88rpx;
|
|
|
+ background: linear-gradient(135deg, #ff6b35 0%, #ff9500 100%);
|
|
|
+ border-radius: 44rpx;
|
|
|
+ border: none;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-container {
|
|
|
background-color: #fff;
|
|
|
- border-radius: 16rpx;
|
|
|
+ border-radius: 20rpx 20rpx 0 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 30rpx;
|
|
|
+ border-bottom: 1rpx solid #eee;
|
|
|
+
|
|
|
+ text {
|
|
|
+ color: #007aff;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333 !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-view {
|
|
|
+ height: 400rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ height: 80rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提交成功弹框样式
|
|
|
+ .success-popup {
|
|
|
+ .popup-content {
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 60rpx 40rpx 40rpx;
|
|
|
+ width: 560rpx;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .success-icon {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+ }
|
|
|
|
|
|
.popup-title {
|
|
|
font-size: 36rpx;
|
|
|
+ font-weight: 600;
|
|
|
color: #333;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .popup-message {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ line-height: 1.6;
|
|
|
+ margin-bottom: 50rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .popup-buttons {
|
|
|
+ display: flex;
|
|
|
+ gap: 20rpx;
|
|
|
+
|
|
|
+ button {
|
|
|
+ flex: 1;
|
|
|
+ height: 80rpx;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cancel-btn {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+
|
|
|
+ .follow-btn {
|
|
|
+ background: linear-gradient(135deg, #ff6b35 0%, #ff9500 100%);
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 二维码弹框样式
|
|
|
+ .qrcode-popup {
|
|
|
+ .qrcode-content {
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 50rpx 40rpx;
|
|
|
+ width: 560rpx;
|
|
|
text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .qrcode-title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .qrcode-image {
|
|
|
+ width: 400rpx;
|
|
|
+ height: 400rpx;
|
|
|
+ margin: 0 auto 30rpx;
|
|
|
+ border: 1rpx solid #eee;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ overflow: hidden;
|
|
|
position: relative;
|
|
|
- margin-bottom: 60rpx;
|
|
|
- font-weight: 500;
|
|
|
|
|
|
- .close-icon {
|
|
|
+ image {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .preview-tip {
|
|
|
position: absolute;
|
|
|
+ left: 0;
|
|
|
right: 0;
|
|
|
- top: 50%;
|
|
|
- transform: translateY(-50%);
|
|
|
- font-size: 50rpx;
|
|
|
- color: #999;
|
|
|
- width: 60rpx;
|
|
|
+ bottom: 0;
|
|
|
height: 60rpx;
|
|
|
+ background: rgba(0, 0, 0, 0.5);
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .apply-methods {
|
|
|
- display: flex;
|
|
|
- justify-content: space-around;
|
|
|
- padding: 0 20rpx;
|
|
|
-
|
|
|
- .method-item {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- gap: 30rpx;
|
|
|
- cursor: pointer;
|
|
|
-
|
|
|
- .method-icon {
|
|
|
- width: 120rpx;
|
|
|
- height: 120rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
-
|
|
|
- image {
|
|
|
- width: 80rpx;
|
|
|
- height: 80rpx;
|
|
|
- }
|
|
|
-
|
|
|
- &.green-bg {
|
|
|
- background-color: #39833b;
|
|
|
- }
|
|
|
-
|
|
|
- &.orange-bg {
|
|
|
- background-color: #FF6B00;
|
|
|
- }
|
|
|
- }
|
|
|
+ color: #fff;
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
|
text {
|
|
|
- font-size: 32rpx;
|
|
|
- color: #333;
|
|
|
- font-weight: 500;
|
|
|
+ margin-left: 10rpx;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ opacity: 0.8;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .qrcode-tip {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+ line-height: 1.5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .qrcode-close-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 80rpx;
|
|
|
+ background: linear-gradient(135deg, #ff6b35 0%, #ff9500 100%);
|
|
|
+ border-radius: 40rpx;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 28rpx;
|
|
|
+ border: none;
|
|
|
}
|
|
|
}
|
|
|
</style>
|