Compare commits
5 Commits
7c23c2c10d
...
25e9db780b
| Author | SHA1 | Date |
|---|---|---|
|
|
25e9db780b | 5 months ago |
|
|
a580c2580a | 5 months ago |
|
|
51987f8b10 | 5 months ago |
|
|
2324c32458 | 5 months ago |
|
|
cdc449472b | 5 months ago |
56 changed files with 3619 additions and 14079 deletions
@ -0,0 +1,381 @@ |
|||
<template> |
|||
<el-dialog |
|||
v-model="showDialog" |
|||
:title="dialogTitle" |
|||
width="700px" |
|||
:close-on-click-modal="false" |
|||
> |
|||
<el-descriptions |
|||
v-if="orderDetail" |
|||
:column="2" |
|||
border |
|||
v-loading="loading" |
|||
> |
|||
<el-descriptions-item label="订单编号"> |
|||
{{ orderDetail.id }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="订单类型"> |
|||
{{ getOrderType(orderDetail.order_type) }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="订单状态"> |
|||
{{ getOrderStatus(orderDetail.order_status) }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="支付类型"> |
|||
{{ getPaymentType(orderDetail.payment_type) }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="订单金额"> |
|||
<span class="text-red-500 font-bold">¥{{ orderDetail.order_amount }}</span> |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="优惠金额" v-if="orderDetail.discount_amount"> |
|||
<span class="text-green-500">¥{{ orderDetail.discount_amount }}</span> |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="课程名称"> |
|||
{{ orderDetail.course_id_name || '-' }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="班级名称"> |
|||
{{ orderDetail.class_id_name || '-' }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="学员姓名"> |
|||
{{ orderDetail.student_name || '-' }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="所属校区"> |
|||
{{ orderDetail.campus_name || '-' }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="客户姓名"> |
|||
{{ orderDetail.resource_id_name || '-' }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="业务员"> |
|||
{{ orderDetail.staff_id_name || '-' }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="赠品信息" v-if="orderDetail.gift_info && orderDetail.gift_info.gift_name"> |
|||
{{ orderDetail.gift_info.gift_name }} |
|||
<el-tag size="small" :type="getGiftStatusType(orderDetail.gift_info.gift_status)" style="margin-left: 8px;"> |
|||
{{ getGiftStatus(orderDetail.gift_info.gift_status) }} |
|||
</el-tag> |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="支付时间" v-if="orderDetail.payment_time"> |
|||
{{ orderDetail.payment_time }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="创建时间"> |
|||
{{ orderDetail.created_at }} |
|||
</el-descriptions-item> |
|||
|
|||
<el-descriptions-item label="订单备注" :span="2" v-if="orderDetail.remark"> |
|||
{{ orderDetail.remark }} |
|||
</el-descriptions-item> |
|||
</el-descriptions> |
|||
|
|||
<!-- 确认支付时的支付凭证上传区域 --> |
|||
<div v-if="isPaymentAction && orderDetail?.order_status === 'pending'" class="payment-voucher-section"> |
|||
<el-divider content-position="left">支付凭证</el-divider> |
|||
|
|||
<el-form :model="paymentForm" label-width="100px" style="margin-top: 20px;"> |
|||
<el-form-item label="上传凭证"> |
|||
<div class="upload-wrapper"> |
|||
<el-upload |
|||
:action="uploadAction" |
|||
:headers="uploadHeaders" |
|||
:show-file-list="true" |
|||
:on-success="handleUploadSuccess" |
|||
:on-error="handleUploadError" |
|||
:before-upload="beforeUpload" |
|||
list-type="picture-card" |
|||
accept="image/*" |
|||
class="voucher-upload" |
|||
> |
|||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon> |
|||
</el-upload> |
|||
<div class="upload-tip"> |
|||
支持 jpg/png/jpeg 格式,单个文件不超过 5MB |
|||
</div> |
|||
</div> |
|||
</el-form-item> |
|||
<el-form-item label="支付备注"> |
|||
<el-input |
|||
v-model="paymentForm.remark" |
|||
type="textarea" |
|||
:rows="3" |
|||
placeholder="请输入支付备注信息(可选)" |
|||
/> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
|
|||
<template #footer> |
|||
<span class="dialog-footer"> |
|||
<el-button @click="showDialog = false">关闭</el-button> |
|||
<el-button |
|||
v-if="isPaymentAction && orderDetail?.order_status === 'pending'" |
|||
type="primary" |
|||
@click="handleConfirmPayment" |
|||
:disabled="paymentForm.vouchers.length === 0" |
|||
> |
|||
确认支付 |
|||
</el-button> |
|||
</span> |
|||
</template> |
|||
</el-dialog> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { ref, computed } from 'vue' |
|||
import { getOrderDetail } from '@/app/api/order_table' |
|||
import { ElMessage } from 'element-plus' |
|||
import { Plus } from '@element-plus/icons-vue' |
|||
import { getToken } from '@/utils/common' |
|||
|
|||
const showDialog = ref(false) |
|||
const loading = ref(false) |
|||
const orderDetail = ref<any>(null) |
|||
const isPaymentAction = ref(false) |
|||
|
|||
// 支付表单数据 |
|||
const paymentForm = ref({ |
|||
vouchers: [] as string[], // 支付凭证URL数组 |
|||
remark: '' // 支付备注 |
|||
}) |
|||
|
|||
// 上传配置 |
|||
const uploadAction = ref(import.meta.env.VITE_APP_BASE_URL + 'sys/image') |
|||
const uploadHeaders = ref({ |
|||
token: getToken() |
|||
}) |
|||
|
|||
const dialogTitle = computed(() => { |
|||
return isPaymentAction.value ? '确认支付' : '订单详情' |
|||
}) |
|||
|
|||
// 订单类型映射 |
|||
const getOrderType = (type: number) => { |
|||
const typeMap: Record<number, string> = { |
|||
1: '新订单', |
|||
2: '续费订单', |
|||
3: '内部员工订单', |
|||
4: '转校', |
|||
5: '客户内转课订单' |
|||
} |
|||
return typeMap[type] || '-' |
|||
} |
|||
|
|||
// 订单状态映射 |
|||
const getOrderStatus = (status: string) => { |
|||
const statusMap: Record<string, string> = { |
|||
pending: '待支付', |
|||
paid: '已支付', |
|||
signed: '待签约', |
|||
completed: '已完成', |
|||
transfer: '转学' |
|||
} |
|||
return statusMap[status] || '-' |
|||
} |
|||
|
|||
// 支付类型映射 |
|||
const getPaymentType = (type: string) => { |
|||
const typeMap: Record<string, string> = { |
|||
cash: '现金支付', |
|||
scan_code: '扫码支付', |
|||
subscription: '订阅支付', |
|||
wxpay_online: '微信在线代付', |
|||
client_wxpay: '客户端微信支付', |
|||
deposit: '定金' |
|||
} |
|||
return typeMap[type] || '-' |
|||
} |
|||
|
|||
// 赠品状态映射 |
|||
const getGiftStatus = (status: number) => { |
|||
const statusMap: Record<number, string> = { |
|||
1: '未使用', |
|||
2: '已使用', |
|||
3: '已过期', |
|||
4: '已作废' |
|||
} |
|||
return statusMap[status] || '-' |
|||
} |
|||
|
|||
// 赠品状态标签类型 |
|||
const getGiftStatusType = (status: number) => { |
|||
const typeMap: Record<number, string> = { |
|||
1: 'success', |
|||
2: 'info', |
|||
3: 'warning', |
|||
4: 'danger' |
|||
} |
|||
return typeMap[status] || 'info' |
|||
} |
|||
|
|||
// 打开弹窗 |
|||
const openDialog = async (orderId: number, forPayment: boolean = false) => { |
|||
showDialog.value = true |
|||
loading.value = true |
|||
isPaymentAction.value = forPayment |
|||
|
|||
// 重置支付表单 |
|||
paymentForm.value = { |
|||
vouchers: [], |
|||
remark: '' |
|||
} |
|||
|
|||
try { |
|||
const res = await getOrderDetail(orderId) |
|||
orderDetail.value = res.data |
|||
} catch (error) { |
|||
ElMessage.error('获取订单详情失败') |
|||
showDialog.value = false |
|||
} finally { |
|||
loading.value = false |
|||
} |
|||
} |
|||
|
|||
// 上传前校验 |
|||
const beforeUpload = (file: any) => { |
|||
const isImage = file.type.startsWith('image/') |
|||
const isLt5M = file.size / 1024 / 1024 < 5 |
|||
|
|||
if (!isImage) { |
|||
ElMessage.error('只能上传图片文件!') |
|||
return false |
|||
} |
|||
if (!isLt5M) { |
|||
ElMessage.error('图片大小不能超过 5MB!') |
|||
return false |
|||
} |
|||
return true |
|||
} |
|||
|
|||
// 上传成功回调 |
|||
const handleUploadSuccess = (response: any, file: any) => { |
|||
if (response.code === 1 && response.data && response.data.url) { |
|||
paymentForm.value.vouchers.push(response.data.url) |
|||
ElMessage.success('上传成功') |
|||
} else { |
|||
ElMessage.error(response.msg || '上传失败') |
|||
} |
|||
} |
|||
|
|||
// 上传失败回调 |
|||
const handleUploadError = () => { |
|||
ElMessage.error('上传失败,请重试') |
|||
} |
|||
|
|||
// 确认支付 |
|||
const handleConfirmPayment = () => { |
|||
if (paymentForm.value.vouchers.length === 0) { |
|||
ElMessage.warning('请上传支付凭证') |
|||
return |
|||
} |
|||
|
|||
// 这里可以调用支付接口 |
|||
console.log('订单ID:', orderDetail.value.id) |
|||
console.log('支付凭证:', paymentForm.value.vouchers) |
|||
console.log('支付备注:', paymentForm.value.remark) |
|||
|
|||
ElMessage.success('支付确认成功,待后端接口实现') |
|||
showDialog.value = false |
|||
} |
|||
|
|||
// 暴露方法供父组件调用 |
|||
defineExpose({ |
|||
openDialog |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.text-red-500 { |
|||
color: #ef4444; |
|||
} |
|||
.text-green-500 { |
|||
color: #10b981; |
|||
} |
|||
.font-bold { |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.payment-voucher-section { |
|||
margin-top: 20px; |
|||
padding: 20px; |
|||
background-color: #f9fafb; |
|||
border-radius: 8px; |
|||
} |
|||
|
|||
/* 上传容器布局 */ |
|||
.upload-wrapper { |
|||
width: 100%; |
|||
display: block; |
|||
overflow: visible; |
|||
} |
|||
|
|||
/* 上传提示文字 */ |
|||
.upload-tip { |
|||
margin-top: 10px; |
|||
padding-top: 10px; |
|||
display: block; |
|||
font-size: 12px; |
|||
color: #999; |
|||
line-height: 1.5; |
|||
clear: both; |
|||
} |
|||
|
|||
/* 上传组件样式 - 强制显示为块级元素 */ |
|||
.voucher-upload { |
|||
width: 100%; |
|||
display: block !important; |
|||
overflow: visible !important; |
|||
} |
|||
|
|||
/* el-upload 组件内部样式穿透 */ |
|||
:deep(.el-upload--picture-card) { |
|||
width: 120px !important; |
|||
height: 120px !important; |
|||
display: inline-block !important; |
|||
vertical-align: top !important; |
|||
margin: 0 8px 8px 0 !important; |
|||
} |
|||
|
|||
:deep(.el-upload-list) { |
|||
display: block !important; |
|||
overflow: visible !important; |
|||
position: relative !important; |
|||
} |
|||
|
|||
:deep(.el-upload-list--picture-card) { |
|||
display: block !important; |
|||
vertical-align: top !important; |
|||
width: 100% !important; |
|||
overflow: visible !important; |
|||
position: relative !important; |
|||
} |
|||
|
|||
:deep(.el-upload-list__item) { |
|||
width: 120px !important; |
|||
height: 120px !important; |
|||
display: inline-block !important; |
|||
margin: 0 8px 8px 0 !important; |
|||
vertical-align: top !important; |
|||
position: relative !important; |
|||
} |
|||
|
|||
.avatar-uploader-icon { |
|||
font-size: 28px; |
|||
color: #8c939d; |
|||
width: 120px; |
|||
height: 120px; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
</style> |
|||
File diff suppressed because it is too large
@ -0,0 +1,225 @@ |
|||
<!-- 体测记录列表弹窗组件 --> |
|||
<template> |
|||
<view class="fitness-record-list-popup" v-if="visible" @click.stop="handleMaskClick"> |
|||
<view class="popup-container" @click.stop> |
|||
<!-- 标题栏 --> |
|||
<view class="popup-header"> |
|||
<text class="popup-title">体测记录</text> |
|||
<view class="close-btn" @click.stop="handleClose"> |
|||
<text>✕</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 体测记录列表 --> |
|||
<view class="fitness-records-container"> |
|||
<!-- 空状态提示 --> |
|||
<view v-if="!records || records.length === 0" class="empty-state"> |
|||
<view class="empty-icon">📊</view> |
|||
<view class="empty-text">暂无体测记录</view> |
|||
<view class="empty-tip">点击下方"新增"按钮添加体测记录</view> |
|||
</view> |
|||
|
|||
<!-- 体测记录列表 --> |
|||
<FitnessRecordCard |
|||
v-for="record in records" |
|||
:key="record.id" |
|||
:record="record" |
|||
@edit="handleEdit" |
|||
/> |
|||
</view> |
|||
|
|||
<!-- 底部操作按钮 --> |
|||
<view class="popup-footer"> |
|||
<view class="footer-btn cancel-btn" @click.stop="handleClose">关闭</view> |
|||
<view class="footer-btn confirm-btn" @click.stop="handleAddNew">新增</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import FitnessRecordCard from '@/components/fitness-record-card/fitness-record-card.vue' |
|||
|
|||
export default { |
|||
name: 'FitnessRecordListPopup', |
|||
components: { |
|||
FitnessRecordCard |
|||
}, |
|||
props: { |
|||
// 是否显示弹窗 |
|||
visible: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
// 体测记录列表 |
|||
records: { |
|||
type: Array, |
|||
default: () => [] |
|||
} |
|||
}, |
|||
methods: { |
|||
// 关闭弹窗 |
|||
handleClose() { |
|||
this.$emit('close') |
|||
}, |
|||
|
|||
// 点击遮罩关闭 |
|||
handleMaskClick() { |
|||
this.handleClose() |
|||
}, |
|||
|
|||
// 新增体测记录 |
|||
handleAddNew() { |
|||
this.$emit('add') |
|||
}, |
|||
|
|||
// 编辑体测记录 |
|||
handleEdit(record) { |
|||
this.$emit('edit', record) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.fitness-record-list-popup { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
display: flex; |
|||
align-items: flex-end; |
|||
justify-content: center; |
|||
z-index: 999; /* 比FitnessRecordPopup的z-index低 */ |
|||
} |
|||
|
|||
.popup-container { |
|||
width: 100%; |
|||
max-height: 80vh; |
|||
background: #FFFFFF; |
|||
border-radius: 32rpx 32rpx 0 0; |
|||
display: flex; |
|||
flex-direction: column; |
|||
animation: slideUp 0.3s ease-out; |
|||
} |
|||
|
|||
@keyframes slideUp { |
|||
from { |
|||
transform: translateY(100%); |
|||
} |
|||
to { |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
|
|||
.popup-header { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 32rpx 32rpx 24rpx; |
|||
border-bottom: 1rpx solid #F0F0F0; |
|||
} |
|||
|
|||
.popup-title { |
|||
font-size: 36rpx; |
|||
font-weight: 600; |
|||
color: #333333; |
|||
} |
|||
|
|||
.close-btn { |
|||
width: 56rpx; |
|||
height: 56rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background: #F5F5F5; |
|||
border-radius: 50%; |
|||
|
|||
text { |
|||
font-size: 40rpx; |
|||
color: #999999; |
|||
line-height: 1; |
|||
} |
|||
} |
|||
|
|||
.fitness-records-container { |
|||
flex: 1; |
|||
overflow-y: auto; |
|||
padding: 24rpx 32rpx; |
|||
max-height: 50vh; |
|||
} |
|||
|
|||
/* 滚动条样式 */ |
|||
.fitness-records-container::-webkit-scrollbar { |
|||
width: 6rpx; |
|||
} |
|||
|
|||
.fitness-records-container::-webkit-scrollbar-track { |
|||
background: transparent; |
|||
} |
|||
|
|||
.fitness-records-container::-webkit-scrollbar-thumb { |
|||
background: #29D3B4; |
|||
border-radius: 3rpx; |
|||
} |
|||
|
|||
.fitness-records-container::-webkit-scrollbar-thumb:hover { |
|||
background: #24B89E; |
|||
} |
|||
|
|||
.empty-state { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 80rpx 0; |
|||
} |
|||
|
|||
.empty-icon { |
|||
font-size: 120rpx; |
|||
line-height: 1; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.empty-text { |
|||
font-size: 28rpx; |
|||
color: #999999; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.empty-tip { |
|||
font-size: 24rpx; |
|||
color: #CCCCCC; |
|||
} |
|||
|
|||
.popup-footer { |
|||
display: flex; |
|||
padding: 24rpx 32rpx; |
|||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom)); |
|||
border-top: 1rpx solid #F0F0F0; |
|||
gap: 24rpx; |
|||
} |
|||
|
|||
.footer-btn { |
|||
flex: 1; |
|||
height: 88rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border-radius: 16rpx; |
|||
font-size: 32rpx; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.cancel-btn { |
|||
background: #F5F5F5; |
|||
color: #666666; |
|||
} |
|||
|
|||
.confirm-btn { |
|||
background: linear-gradient(135deg, #29D3B4 0%, #24B89E 100%); |
|||
color: #FFFFFF; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,505 @@ |
|||
<!--支付凭证上传弹窗组件--> |
|||
<template> |
|||
<view class="payment-voucher-wrapper"> |
|||
<!-- 遮罩层 --> |
|||
<view class="popup-mask" @click="handleCancel"></view> |
|||
|
|||
<!-- 弹窗内容 --> |
|||
<view class="payment-voucher-popup"> |
|||
<view class="popup-content"> |
|||
<view class="popup-header"> |
|||
<text class="popup-title">上传支付凭证</text> |
|||
<view class="close-btn" @click="handleCancel"> |
|||
<text class="close-icon">✕</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="popup-body"> |
|||
<!-- 订单信息展示 --> |
|||
<view class="order-info-section"> |
|||
<view class="info-row"> |
|||
<text class="info-label">订单号:</text> |
|||
<text class="info-value">{{ orderInfo.order_no }}</text> |
|||
</view> |
|||
<view class="info-row"> |
|||
<text class="info-label">课程类型:</text> |
|||
<text class="info-value">{{ orderInfo.product_name }}</text> |
|||
</view> |
|||
<view class="info-row"> |
|||
<text class="info-label">支付金额:</text> |
|||
<text class="info-value amount">¥{{ orderInfo.total_amount }}</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 图片上传区域 --> |
|||
<view class="upload-section"> |
|||
<view class="section-title">支付凭证</view> |
|||
<view class="upload-tip">最多上传9张图片</view> |
|||
|
|||
<view class="image-list"> |
|||
<view |
|||
v-for="(image, index) in imageList" |
|||
:key="index" |
|||
class="image-item" |
|||
> |
|||
<image :src="image" class="preview-image" mode="aspectFill"></image> |
|||
<view class="delete-btn" @click="deleteImage(index)"> |
|||
<text class="delete-icon">×</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<view |
|||
v-if="imageList.length < 9" |
|||
class="upload-btn" |
|||
@click="chooseImage" |
|||
> |
|||
<text class="upload-icon">+</text> |
|||
<text class="upload-text">上传图片</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="popup-footer"> |
|||
<view class="footer-btn cancel-btn" @click="handleCancel"> |
|||
<text>取消</text> |
|||
</view> |
|||
<view |
|||
class="footer-btn confirm-btn" |
|||
:class="{ disabled: !canSubmit }" |
|||
@click="handleConfirm" |
|||
> |
|||
<text>提交</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { uploadFile } from '@/common/util.js' |
|||
|
|||
export default { |
|||
name: 'PaymentVoucherPopup', |
|||
|
|||
props: { |
|||
// 订单信息 |
|||
orderInfo: { |
|||
type: Object, |
|||
default: () => ({ |
|||
order_no: '', |
|||
product_name: '', |
|||
total_amount: '0.00' |
|||
}) |
|||
} |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
imageList: [], // 图片列表 |
|||
uploading: false |
|||
} |
|||
}, |
|||
|
|||
computed: { |
|||
// 是否可以提交 |
|||
canSubmit() { |
|||
return this.imageList.length > 0 && !this.uploading |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
/** |
|||
* 选择图片 |
|||
*/ |
|||
chooseImage() { |
|||
const remainCount = 9 - this.imageList.length |
|||
|
|||
uni.chooseImage({ |
|||
count: remainCount, |
|||
sizeType: ['compressed'], |
|||
sourceType: ['album', 'camera'], |
|||
success: (res) => { |
|||
const tempFilePaths = res.tempFilePaths |
|||
|
|||
// 上传图片 |
|||
this.uploadImages(tempFilePaths) |
|||
}, |
|||
fail: (err) => { |
|||
console.error('选择图片失败:', err) |
|||
uni.showToast({ title: '选择图片失败', icon: 'none' }) |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 上传图片 |
|||
*/ |
|||
async uploadImages(filePaths) { |
|||
this.uploading = true |
|||
uni.showLoading({ title: '上传中...' }) |
|||
|
|||
try { |
|||
const uploadPromises = filePaths.map(filePath => this.uploadSingleImage(filePath)) |
|||
const results = await Promise.all(uploadPromises) |
|||
|
|||
// 将上传成功的图片URL添加到列表 |
|||
results.forEach(url => { |
|||
if (url) { |
|||
this.imageList.push(url) |
|||
} |
|||
}) |
|||
|
|||
uni.hideLoading() |
|||
|
|||
if (results.some(url => url)) { |
|||
uni.showToast({ title: '上传成功', icon: 'success' }) |
|||
} |
|||
} catch (error) { |
|||
uni.hideLoading() |
|||
console.error('上传图片异常:', error) |
|||
uni.showToast({ title: '上传失败', icon: 'none' }) |
|||
} finally { |
|||
this.uploading = false |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 上传单张图片 |
|||
*/ |
|||
uploadSingleImage(filePath) { |
|||
return new Promise((resolve, reject) => { |
|||
uploadFile( |
|||
filePath, |
|||
(fileData) => { |
|||
// 成功回调: fileData = { url, extname, name } |
|||
if (fileData && fileData.url) { |
|||
resolve(fileData.url) |
|||
} else { |
|||
console.error('上传成功但未返回URL') |
|||
resolve(null) |
|||
} |
|||
}, |
|||
(error) => { |
|||
// 失败回调 |
|||
console.error('上传请求失败:', error) |
|||
resolve(null) |
|||
} |
|||
) |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 删除图片 |
|||
*/ |
|||
deleteImage(index) { |
|||
uni.showModal({ |
|||
title: '确认删除', |
|||
content: '确定要删除这张图片吗?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
this.imageList.splice(index, 1) |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 取消 |
|||
*/ |
|||
handleCancel() { |
|||
this.$emit('cancel') |
|||
}, |
|||
|
|||
/** |
|||
* 确认提交 |
|||
*/ |
|||
handleConfirm() { |
|||
if (!this.canSubmit) { |
|||
uni.showToast({ title: '请先上传支付凭证', icon: 'none' }) |
|||
return |
|||
} |
|||
|
|||
// 将图片数组转为逗号分隔的字符串 |
|||
const payment_voucher = this.imageList.join(',') |
|||
|
|||
this.$emit('confirm', { |
|||
payment_voucher: payment_voucher, |
|||
order_id: this.orderInfo.id || this.orderInfo._raw?.id |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 重置数据 |
|||
*/ |
|||
reset() { |
|||
this.imageList = [] |
|||
this.uploading = false |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.payment-voucher-wrapper { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
z-index: 9998; |
|||
display: flex; |
|||
align-items: flex-end; |
|||
} |
|||
|
|||
.popup-mask { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
z-index: 1; |
|||
} |
|||
|
|||
.payment-voucher-popup { |
|||
position: relative; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
width: 100%; |
|||
background: #2A2A2A; |
|||
border-radius: 24rpx 24rpx 0 0; |
|||
overflow: hidden; |
|||
z-index: 2; |
|||
box-shadow: 0 -8rpx 32rpx rgba(0, 0, 0, 0.3); |
|||
animation: slideUp 0.3s ease; |
|||
} |
|||
|
|||
@keyframes slideUp { |
|||
from { |
|||
transform: translateY(100%); |
|||
} |
|||
to { |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
|
|||
.popup-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
max-height: 90vh; |
|||
} |
|||
|
|||
.popup-header { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 32rpx 40rpx; |
|||
border-bottom: 1px solid #404040; |
|||
} |
|||
|
|||
.popup-title { |
|||
font-size: 32rpx; |
|||
font-weight: 600; |
|||
color: #ffffff; |
|||
} |
|||
|
|||
.close-btn { |
|||
width: 56rpx; |
|||
height: 56rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background: rgba(255, 255, 255, 0.1); |
|||
border-radius: 50%; |
|||
transition: all 0.3s ease; |
|||
|
|||
&:active { |
|||
background: rgba(255, 255, 255, 0.15); |
|||
} |
|||
} |
|||
|
|||
.close-icon { |
|||
font-size: 40rpx; |
|||
color: #ffffff; |
|||
line-height: 1; |
|||
} |
|||
|
|||
.popup-body { |
|||
flex: 1; |
|||
padding: 32rpx 40rpx; |
|||
overflow-y: auto; |
|||
} |
|||
|
|||
.order-info-section { |
|||
background: rgba(41, 211, 180, 0.05); |
|||
border-radius: 16rpx; |
|||
padding: 24rpx; |
|||
margin-bottom: 32rpx; |
|||
border-left: 4rpx solid #29D3B4; |
|||
} |
|||
|
|||
.info-row { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
margin-bottom: 16rpx; |
|||
|
|||
&:last-child { |
|||
margin-bottom: 0; |
|||
} |
|||
} |
|||
|
|||
.info-label { |
|||
font-size: 28rpx; |
|||
color: #999999; |
|||
min-width: 140rpx; |
|||
} |
|||
|
|||
.info-value { |
|||
font-size: 28rpx; |
|||
color: #ffffff; |
|||
flex: 1; |
|||
text-align: right; |
|||
|
|||
&.amount { |
|||
color: #FFC107; |
|||
font-weight: 600; |
|||
font-size: 32rpx; |
|||
} |
|||
} |
|||
|
|||
.upload-section { |
|||
margin-bottom: 32rpx; |
|||
} |
|||
|
|||
.section-title { |
|||
font-size: 28rpx; |
|||
font-weight: 600; |
|||
color: #ffffff; |
|||
margin-bottom: 12rpx; |
|||
} |
|||
|
|||
.upload-tip { |
|||
font-size: 24rpx; |
|||
color: #999999; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.image-list { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
gap: 16rpx; |
|||
} |
|||
|
|||
.image-item { |
|||
position: relative; |
|||
width: 200rpx; |
|||
height: 200rpx; |
|||
border-radius: 12rpx; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.preview-image { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
.delete-btn { |
|||
position: absolute; |
|||
top: 8rpx; |
|||
right: 8rpx; |
|||
width: 44rpx; |
|||
height: 44rpx; |
|||
background: rgba(0, 0, 0, 0.6); |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
|
|||
&:active { |
|||
background: rgba(0, 0, 0, 0.8); |
|||
} |
|||
} |
|||
|
|||
.delete-icon { |
|||
font-size: 32rpx; |
|||
color: #ffffff; |
|||
line-height: 1; |
|||
} |
|||
|
|||
.upload-btn { |
|||
width: 200rpx; |
|||
height: 200rpx; |
|||
border: 2px dashed #404040; |
|||
border-radius: 12rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background: rgba(255, 255, 255, 0.02); |
|||
transition: all 0.3s ease; |
|||
|
|||
&:active { |
|||
background: rgba(255, 255, 255, 0.05); |
|||
border-color: #29D3B4; |
|||
} |
|||
} |
|||
|
|||
.upload-icon { |
|||
font-size: 48rpx; |
|||
color: #666666; |
|||
line-height: 1; |
|||
margin-bottom: 8rpx; |
|||
} |
|||
|
|||
.upload-text { |
|||
font-size: 24rpx; |
|||
color: #999999; |
|||
} |
|||
|
|||
.popup-footer { |
|||
display: flex; |
|||
gap: 24rpx; |
|||
padding: 24rpx 40rpx; |
|||
border-top: 1px solid #404040; |
|||
background: #2A2A2A; |
|||
} |
|||
|
|||
.footer-btn { |
|||
flex: 1; |
|||
height: 88rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border-radius: 16rpx; |
|||
font-size: 30rpx; |
|||
font-weight: 500; |
|||
transition: all 0.3s ease; |
|||
} |
|||
|
|||
.cancel-btn { |
|||
background: rgba(255, 255, 255, 0.1); |
|||
color: #ffffff; |
|||
|
|||
&:active { |
|||
background: rgba(255, 255, 255, 0.15); |
|||
} |
|||
} |
|||
|
|||
.confirm-btn { |
|||
background: #29D3B4; |
|||
color: #ffffff; |
|||
|
|||
&:active { |
|||
background: #1fb396; |
|||
} |
|||
|
|||
&.disabled { |
|||
background: #404040; |
|||
color: #666666; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,207 @@ |
|||
<!--二维码支付弹窗组件--> |
|||
<template> |
|||
<view class="qrcode-payment-modal"> |
|||
<!-- 弹窗头部 --> |
|||
<view class="modal-header"> |
|||
<text class="modal-title">扫码支付</text> |
|||
<view class="close-btn" @click="handleClose"> |
|||
<text>✕</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 订单信息 --> |
|||
<view class="order-info"> |
|||
<view class="info-row"> |
|||
<text class="label">订单号:</text> |
|||
<text class="value">{{ paymentData.order.order_no }}</text> |
|||
</view> |
|||
<view class="info-row"> |
|||
<text class="label">支付金额:</text> |
|||
<text class="amount">¥{{ paymentData.order.total_amount }}</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 二维码区域 --> |
|||
<view class="qrcode-container"> |
|||
<image |
|||
v-if="paymentData.qrcodeImage" |
|||
:src="paymentData.qrcodeImage" |
|||
class="qrcode-image" |
|||
mode="aspectFit" |
|||
/> |
|||
<text v-else class="qrcode-placeholder">二维码加载中...</text> |
|||
<text class="qrcode-tip">请使用微信扫码完成支付</text> |
|||
</view> |
|||
|
|||
<!-- 操作按钮 --> |
|||
<view class="modal-buttons"> |
|||
<view class="btn secondary" @click="handleClose">取消支付</view> |
|||
<view class="btn primary" @click="handleConfirm">确认已支付</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'QRCodePaymentDialog', |
|||
props: { |
|||
paymentData: { |
|||
type: Object, |
|||
required: true |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
handleClose() { |
|||
this.$emit('close') |
|||
}, |
|||
|
|||
handleConfirm() { |
|||
this.$emit('confirm') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.qrcode-payment-modal { |
|||
background: #2A2A2A; |
|||
border-radius: 24rpx; |
|||
padding: 48rpx; |
|||
width: 600rpx; |
|||
max-width: 90vw; |
|||
} |
|||
|
|||
.modal-header { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
margin-bottom: 40rpx; |
|||
} |
|||
|
|||
.modal-title { |
|||
font-size: 36rpx; |
|||
font-weight: 600; |
|||
color: #ffffff; |
|||
} |
|||
|
|||
.close-btn { |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background: rgba(255, 255, 255, 0.1); |
|||
border-radius: 50%; |
|||
font-size: 32rpx; |
|||
color: #ffffff; |
|||
transition: all 0.3s ease; |
|||
|
|||
&:active { |
|||
background: rgba(255, 255, 255, 0.2); |
|||
} |
|||
} |
|||
|
|||
.order-info { |
|||
background: rgba(255, 255, 255, 0.05); |
|||
border-radius: 16rpx; |
|||
padding: 32rpx; |
|||
margin-bottom: 40rpx; |
|||
} |
|||
|
|||
.info-row { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
margin-bottom: 20rpx; |
|||
|
|||
&:last-child { |
|||
margin-bottom: 0; |
|||
} |
|||
} |
|||
|
|||
.label { |
|||
font-size: 28rpx; |
|||
color: #999999; |
|||
} |
|||
|
|||
.value { |
|||
font-size: 28rpx; |
|||
color: #ffffff; |
|||
} |
|||
|
|||
.amount { |
|||
font-size: 40rpx; |
|||
font-weight: 600; |
|||
color: #FFC107; |
|||
} |
|||
|
|||
.qrcode-container { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 40rpx; |
|||
background: #ffffff; |
|||
border-radius: 16rpx; |
|||
margin-bottom: 40rpx; |
|||
} |
|||
|
|||
.qrcode-image { |
|||
width: 400rpx; |
|||
height: 400rpx; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.qrcode-placeholder { |
|||
width: 400rpx; |
|||
height: 400rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 28rpx; |
|||
color: #999999; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.qrcode-tip { |
|||
font-size: 26rpx; |
|||
color: #666666; |
|||
text-align: center; |
|||
} |
|||
|
|||
.modal-buttons { |
|||
display: flex; |
|||
gap: 24rpx; |
|||
} |
|||
|
|||
.btn { |
|||
flex: 1; |
|||
height: 88rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border-radius: 44rpx; |
|||
font-size: 30rpx; |
|||
font-weight: 500; |
|||
transition: all 0.3s ease; |
|||
|
|||
&.secondary { |
|||
background: rgba(255, 255, 255, 0.1); |
|||
color: #ffffff; |
|||
|
|||
&:active { |
|||
background: rgba(255, 255, 255, 0.15); |
|||
} |
|||
} |
|||
|
|||
&.primary { |
|||
background: #29D3B4; |
|||
color: #ffffff; |
|||
|
|||
&:active { |
|||
background: #1fb396; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
File diff suppressed because it is too large
@ -1,431 +0,0 @@ |
|||
// 客户详情页样式文件 |
|||
.assemble { |
|||
background-color: #292929; |
|||
min-height: 100vh; |
|||
} |
|||
|
|||
.content { |
|||
padding: 20rpx; |
|||
} |
|||
|
|||
.tab-switcher-container { |
|||
margin: 20rpx 0; |
|||
} |
|||
|
|||
// 学生信息区域 |
|||
.student-section { |
|||
margin-top: 20rpx; |
|||
|
|||
.section-header { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 20rpx; |
|||
|
|||
.section-title { |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
color: #fff; |
|||
} |
|||
|
|||
.add-student-btn { |
|||
display: flex; |
|||
align-items: center; |
|||
background: #29d3b4; |
|||
color: #fff; |
|||
border-radius: 20rpx; |
|||
padding: 12rpx 20rpx; |
|||
font-size: 24rpx; |
|||
|
|||
.add-icon { |
|||
margin-right: 8rpx; |
|||
font-weight: bold; |
|||
font-size: 20rpx; |
|||
} |
|||
|
|||
&:active { |
|||
background: #1ea08e; |
|||
transform: scale(0.95); |
|||
} |
|||
} |
|||
} |
|||
|
|||
.student-cards { |
|||
width: 100%; |
|||
min-height: 600rpx; |
|||
|
|||
.student-swiper { |
|||
width: 100%; |
|||
height: 560rpx; |
|||
|
|||
.student-swiper-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 580rpx; |
|||
padding: 20rpx; |
|||
box-sizing: border-box; |
|||
background-color: #434544; |
|||
border-radius: 16rpx; |
|||
margin: 0 10rpx; |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.popup-footer { |
|||
display: flex; |
|||
padding: 30rpx 40rpx; |
|||
padding-bottom: calc(30rpx + env(safe-area-inset-bottom)); |
|||
border-top: 1px solid #333; |
|||
gap: 30rpx; |
|||
flex-shrink: 0; /* 确保底部按钮区域不被压缩 */ |
|||
background: #1a1a1a; /* 确保背景色一致 */ |
|||
|
|||
.popup-footer-btns { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
|
|||
.footer-btn { |
|||
flex: 1; |
|||
height: 88rpx; |
|||
display: flex; |
|||
width: 45%; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border-radius: 12rpx; |
|||
font-size: 32rpx; |
|||
font-weight: 500; |
|||
|
|||
&.cancel-btn { |
|||
background: #cccccc; |
|||
} |
|||
|
|||
&.confirm-btn { |
|||
background: linear-gradient(45deg, #29D3B4, #1DB584); |
|||
color: #ffffff; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
// 课程、通话、体测记录等区域 |
|||
.course-section, .call-section, .fitness-section, .study-plan-section { |
|||
background-color: #434544; |
|||
border-radius: 16rpx; |
|||
margin: 20rpx 0; |
|||
|
|||
.section-header { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 20rpx; |
|||
|
|||
.context-title { |
|||
font-size: 28rpx; |
|||
font-weight: bold; |
|||
color: #fff; |
|||
} |
|||
|
|||
.add-record-btn { |
|||
display: flex; |
|||
align-items: center; |
|||
background: #29d3b4; |
|||
color: #fff; |
|||
border-radius: 20rpx; |
|||
padding: 12rpx 20rpx; |
|||
font-size: 24rpx; |
|||
|
|||
.add-icon { |
|||
margin-right: 8rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
&:active { |
|||
background: #1ea08e; |
|||
transform: scale(0.95); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 操作按钮区域 - 独立于Swiper外部 |
|||
.student-section .action-buttons-section { |
|||
display: flex; |
|||
gap: 8rpx; |
|||
margin-top: 15rpx; |
|||
padding: 15rpx; |
|||
flex-wrap: nowrap; |
|||
height: 100rpx; |
|||
box-sizing: border-box; |
|||
overflow-x: auto; |
|||
overflow-y: hidden; |
|||
-webkit-overflow-scrolling: touch; |
|||
background-color: #434544; |
|||
border-radius: 16rpx; |
|||
margin: 15rpx 0; |
|||
|
|||
&::-webkit-scrollbar { |
|||
display: none; |
|||
} |
|||
|
|||
.action-item { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background: rgba(255, 255, 255, 0.05); |
|||
border: 1px solid rgba(41, 211, 180, 0.3); |
|||
border-radius: 8rpx; |
|||
padding: 12rpx 8rpx; |
|||
min-width: 90rpx; |
|||
flex-shrink: 0; |
|||
transition: all 0.3s ease; |
|||
|
|||
.action-icon { |
|||
font-size: 24rpx; |
|||
margin-bottom: 5rpx; |
|||
line-height: 1; |
|||
} |
|||
|
|||
.action-text { |
|||
font-size: 18rpx; |
|||
color: #fff; |
|||
text-align: center; |
|||
line-height: 1.2; |
|||
word-break: break-all; |
|||
} |
|||
|
|||
&:active { |
|||
background: rgba(41, 211, 180, 0.2); |
|||
border-color: #29d3b4; |
|||
transform: scale(0.95); |
|||
|
|||
.action-text { |
|||
color: #29d3b4; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 通用空状态样式 |
|||
.empty-state { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 60rpx 20rpx; |
|||
min-height: 200rpx; |
|||
|
|||
.empty-icon { |
|||
font-size: 60rpx; |
|||
opacity: 0.6; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.empty-text { |
|||
color: #ccc; |
|||
font-size: 28rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.empty-add-btn { |
|||
background: #29d3b4; |
|||
color: #fff; |
|||
padding: 12rpx 24rpx; |
|||
border-radius: 20rpx; |
|||
font-size: 24rpx; |
|||
transition: all 0.3s ease; |
|||
|
|||
&:active { |
|||
background: #1ea08e; |
|||
transform: scale(0.95); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 备注弹窗样式 |
|||
.remark-dialog { |
|||
width: 600rpx; |
|||
padding: 30rpx; |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
|
|||
textarea { |
|||
width: 100%; |
|||
height: 200rpx; |
|||
padding: 20rpx; |
|||
border: 2rpx solid #e9ecef; |
|||
border-radius: 12rpx; |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
background-color: #fff; |
|||
box-sizing: border-box; |
|||
resize: none; |
|||
|
|||
&::placeholder { |
|||
color: #999; |
|||
} |
|||
|
|||
&:focus { |
|||
border-color: #29d3b4; |
|||
outline: none; |
|||
box-shadow: 0 0 0 2rpx rgba(41, 211, 180, 0.1); |
|||
} |
|||
} |
|||
|
|||
.dialog-btns { |
|||
display: flex; |
|||
gap: 20rpx; |
|||
margin-top: 30rpx; |
|||
|
|||
.btn { |
|||
flex: 1; |
|||
padding: 20rpx; |
|||
border-radius: 8rpx; |
|||
font-size: 28rpx; |
|||
text-align: center; |
|||
|
|||
&.cancel { |
|||
background: #f8f9fa; |
|||
color: #666; |
|||
border: 2rpx solid #e9ecef; |
|||
} |
|||
|
|||
&.confirm { |
|||
background: #29d3b4; |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 二维码支付弹窗样式 |
|||
.qrcode-payment-modal { |
|||
width: 600rpx; |
|||
background: #fff; |
|||
border-radius: 20rpx; |
|||
overflow: hidden; |
|||
|
|||
.modal-header { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 40rpx 40rpx 20rpx; |
|||
border-bottom: 1px solid #f0f0f0; |
|||
|
|||
.modal-title { |
|||
font-size: 36rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
} |
|||
|
|||
.close-btn { |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border-radius: 50%; |
|||
background: #f5f5f5; |
|||
color: #666; |
|||
font-size: 32rpx; |
|||
|
|||
&:active { |
|||
background: #e5e5e5; |
|||
transform: scale(0.95); |
|||
} |
|||
} |
|||
} |
|||
|
|||
.order-info { |
|||
padding: 30rpx 40rpx; |
|||
|
|||
.info-row { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 20rpx; |
|||
|
|||
.label { |
|||
font-size: 28rpx; |
|||
color: #666; |
|||
margin-right: 20rpx; |
|||
} |
|||
|
|||
.value { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
flex: 1; |
|||
} |
|||
|
|||
.amount { |
|||
font-size: 32rpx; |
|||
color: #ff4757; |
|||
font-weight: 600; |
|||
flex: 1; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.qrcode-container { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
padding: 40rpx; |
|||
background: #fafafa; |
|||
|
|||
.qrcode-image { |
|||
width: 300rpx; |
|||
height: 300rpx; |
|||
border: 1px solid #e5e5e5; |
|||
border-radius: 12rpx; |
|||
background: #fff; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.qrcode-tip { |
|||
font-size: 24rpx; |
|||
color: #666; |
|||
text-align: center; |
|||
line-height: 1.4; |
|||
} |
|||
} |
|||
|
|||
.modal-buttons { |
|||
display: flex; |
|||
padding: 30rpx 40rpx 40rpx; |
|||
gap: 20rpx; |
|||
|
|||
.btn { |
|||
flex: 1; |
|||
height: 80rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border-radius: 40rpx; |
|||
font-size: 28rpx; |
|||
font-weight: 500; |
|||
|
|||
&.secondary { |
|||
background: #f5f5f5; |
|||
color: #666; |
|||
|
|||
&:active { |
|||
background: #e5e5e5; |
|||
transform: scale(0.98); |
|||
} |
|||
} |
|||
|
|||
&.primary { |
|||
background: #29d3b4; |
|||
color: #fff; |
|||
|
|||
&:active { |
|||
background: #1ea08e; |
|||
transform: scale(0.98); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -1,164 +0,0 @@ |
|||
<template> |
|||
<view class="dark-table-container"> |
|||
<view v-for="(row, rIdx) in data" :key="rIdx" class="card"> |
|||
<view class="card-title" @click="toggleExpand(rIdx)"> |
|||
{{ row.channel }} |
|||
<text class="expand-icon">{{ expanded[rIdx] ? '▲' : '▼' }}</text> |
|||
</view> |
|||
<view class="card-content"> |
|||
<view |
|||
class="card-row" |
|||
v-for="(col, cIdx) in getVisibleColumns(rIdx)" |
|||
:key="cIdx" |
|||
> |
|||
<view class="card-label"> |
|||
{{ col.label }} |
|||
<text v-if="col.tip" class="tip" @click.stop="showTip(col.tip)">?</text> |
|||
</view> |
|||
<view class="card-value">{{ row[col.key] || '-' }}</view> |
|||
</view> |
|||
</view> |
|||
<view v-if="columns.length > 6" class="expand-btn" @click="toggleExpand(rIdx)"> |
|||
{{ expanded[rIdx] ? '收起' : '展开全部' }} |
|||
</view> |
|||
</view> |
|||
<!-- 说明弹窗 --> |
|||
<uni-popup ref="popup" type="center"> |
|||
<view class="popup-content">{{ tipContent }}</view> |
|||
</uni-popup> |
|||
<AQTabber></AQTabber> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|||
|
|||
export default { |
|||
components: { |
|||
AQTabber, |
|||
}, |
|||
data() { |
|||
return { |
|||
columns: [ |
|||
{ label: '渠道', key: 'channel' }, |
|||
{ label: '资源数', key: 'resource', tip: '本月的新资源' }, |
|||
{ label: '到访数(一访)', key: 'visit1', tip: '本月资源的一访到访数' }, |
|||
{ label: '到访率(一访)', key: 'visitRate1', tip: '一访到访数/本月新资源数' }, |
|||
{ label: '到访数(二访)', key: 'visit2', tip: '二访到访数/一访到访数' }, |
|||
{ label: '到访率(二访)', key: 'visitRate2', tip: '二访到访数/一访到访数' }, |
|||
{ label: '关单数(一访)', key: 'close1', tip: '本月一访到访的关单数' }, |
|||
{ label: '关单率(一访)', key: 'closeRate1', tip: '一访关单数/一访到访数' }, |
|||
{ label: '关单数(二访)', key: 'close2', tip: '二访到访的关单数' }, |
|||
{ label: '关单率(二访)', key: 'closeRate2', tip: '二访关单数/二访到访数' }, |
|||
{ label: '月总转', key: 'monthTrans', tip: '关单数(合计)/资源数' }, |
|||
{ label: '往月到访数', key: 'lastMonthVisit', tip: '本月资源在往月到访的到访数' }, |
|||
{ label: '月共到访', key: 'monthTotalVisit', tip: '本月资源任在本月到访/关单' }, |
|||
{ label: '往月关单数', key: 'lastMonthClose', tip: '本月关单-往月关单' }, |
|||
{ label: '月共关单', key: 'monthTotalClose', tip: '本月关单+往月关单' }, |
|||
], |
|||
data: [ |
|||
{ channel: '体检包(地推)', resource: 10, visit1: 5, visitRate1: '50%', visit2: 2, visitRate2: '40%', close1: 1, closeRate1: '20%', close2: 1, closeRate2: '50%', monthTrans: '10%', lastMonthVisit: 0, monthTotalVisit: 5, lastMonthClose: 0, monthTotalClose: 1 }, |
|||
], |
|||
tipContent: '', |
|||
expanded: {}, |
|||
} |
|||
}, |
|||
methods: { |
|||
showTip(content) { |
|||
this.tipContent = content |
|||
this.$refs.popup.open() |
|||
}, |
|||
toggleExpand(idx) { |
|||
this.$set(this.expanded, idx, !this.expanded[idx]) |
|||
}, |
|||
getVisibleColumns(idx) { |
|||
// 只展示前5个字段,展开后展示全部(不含渠道) |
|||
const cols = this.columns.slice(1) |
|||
if (this.expanded[idx]) return cols |
|||
return cols.slice(0, 5) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.dark-table-container { |
|||
background: #18181c; |
|||
color: #f1f1f1; |
|||
min-height: 100vh; |
|||
padding: 24rpx 12rpx; |
|||
} |
|||
.card { |
|||
background: #23232a; |
|||
border-radius: 18rpx; |
|||
box-shadow: 0 4rpx 24rpx rgba(0,0,0,0.18); |
|||
margin-bottom: 32rpx; |
|||
padding: 24rpx 20rpx 8rpx 20rpx; |
|||
transition: box-shadow 0.2s; |
|||
} |
|||
.card-title { |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
margin-bottom: 18rpx; |
|||
color: #ffb300; |
|||
letter-spacing: 2rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
cursor: pointer; |
|||
} |
|||
.expand-icon { |
|||
font-size: 24rpx; |
|||
color: #bdbdbd; |
|||
margin-left: 12rpx; |
|||
} |
|||
.card-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 12rpx; |
|||
overflow: hidden; |
|||
transition: max-height 0.3s; |
|||
} |
|||
.card-row { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
border-bottom: 1px dashed #333; |
|||
padding: 8rpx 0; |
|||
} |
|||
.card-label { |
|||
color: #bdbdbd; |
|||
font-size: 26rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
.card-value { |
|||
color: #f1f1f1; |
|||
font-size: 26rpx; |
|||
text-align: right; |
|||
max-width: 60%; |
|||
word-break: break-all; |
|||
} |
|||
.tip { |
|||
color: #ffb300; |
|||
margin-left: 8rpx; |
|||
font-size: 24rpx; |
|||
cursor: pointer; |
|||
} |
|||
.expand-btn { |
|||
color: #ffb300; |
|||
text-align: center; |
|||
font-size: 26rpx; |
|||
margin: 10rpx 0 0 0; |
|||
padding-bottom: 8rpx; |
|||
cursor: pointer; |
|||
} |
|||
.popup-content { |
|||
background: #23232a; |
|||
color: #fff; |
|||
padding: 32rpx; |
|||
border-radius: 16rpx; |
|||
min-width: 300rpx; |
|||
text-align: center; |
|||
} |
|||
</style> |
|||
File diff suppressed because it is too large
@ -1,365 +0,0 @@ |
|||
<!--编辑客户--> |
|||
<template> |
|||
<view class="assemble"> |
|||
<!--切换--> |
|||
<view class="tab_section"> |
|||
<fui-segmented-control |
|||
:values="optionTable" |
|||
:current="(Number(optionTableId))" |
|||
type="button" |
|||
radius="8" |
|||
height="80" |
|||
color="#29d3b4" |
|||
bold="true" |
|||
@click="segmented"> |
|||
</fui-segmented-control> |
|||
</view> |
|||
|
|||
<!-- 客户资源修改记录--> |
|||
<scroll-view |
|||
v-show="filteredData.type == `resource`" |
|||
scroll-y="true" |
|||
:lower-threshold="lowerThreshold" |
|||
@scrolltolower="loadMoreData" |
|||
style="margin-top:40rpx;height: 80vh;" |
|||
> |
|||
<!--时间轴--> |
|||
<view class="table_list"> |
|||
<fui-timeaxis background="#292929" :padding="['36rpx','16rpx']"> |
|||
<fui-timeaxis-node |
|||
:lineColor="k<3 ? v.activeColor:'#ccc'" |
|||
:lined="k!==tableList.length-1" |
|||
v-for="(v,k) in tableList" |
|||
:key="k" |
|||
> |
|||
<!--inco--> |
|||
<view |
|||
class="fui-node" |
|||
:style="{borderColor:(k != tableList.length-1 ? '#29d3b4' :'' ) }" |
|||
> |
|||
</view> |
|||
<template v-slot:right> |
|||
<view |
|||
class="fui-process__node table_itme" |
|||
:style="{paddingBottom:(k !== tableList.length-1 ? '50rpx' :'0rpx')}" |
|||
:class="{'fui-node__pb':k!==tableList.length-1}" |
|||
> |
|||
|
|||
<view class="fui-title"> |
|||
<!--修改时间--> |
|||
{{v.modification_time}} |
|||
</view> |
|||
<view class="itme_box"> |
|||
<view class="title_name">修改人:{{v.staff_id_name}} 修改了如下内容</view> |
|||
<view class="table_section"> |
|||
<table class="table_box"> |
|||
<!-- 自定义表头 --> |
|||
<thead> |
|||
<tr> |
|||
<th style="width: 30%; border: 1px solid #ddd; padding: 12rpx;">字段名称</th> |
|||
<th style="width: 34%; border: 1px solid #ddd; padding: 12rpx;">原数据</th> |
|||
<th style="width: 34%; border: 1px solid #ddd; padding: 12rpx;">新数据</th> |
|||
</tr> |
|||
</thead> |
|||
|
|||
<!-- 自定义每一行数据 --> |
|||
<tbody> |
|||
<tr v-for="(row, index) in v.update_arr" :key="index"> |
|||
<td style="width: 30%; border: 1px solid #ddd; padding: 12rpx;">{{ row.field_name_zh }}</td> |
|||
<td style="width: 34%; border: 1px solid #ddd; padding: 12rpx;">{{ row.old_value }}</td> |
|||
<td style="width: 34%; border: 1px solid #ddd; padding: 12rpx;">{{ row.new_value }}</td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
</fui-timeaxis-node> |
|||
</fui-timeaxis> |
|||
</view> |
|||
</scroll-view> |
|||
|
|||
<!-- 六要素修改记录--> |
|||
<scroll-view |
|||
v-show="filteredData.type == `six_speed`" |
|||
scroll-y="true" |
|||
:lower-threshold="lowerThreshold" |
|||
@scrolltolower="loadMoreData" |
|||
style="margin-top:40rpx;height: 80vh;" |
|||
> |
|||
<!--时间轴--> |
|||
<view class="table_list"> |
|||
<fui-timeaxis background="#292929" :padding="['36rpx','16rpx']"> |
|||
<fui-timeaxis-node |
|||
:lineColor="k<3?v.activeColor:'#ccc'" |
|||
:lined="k!==tableList.length-1" |
|||
v-for="(v,k) in tableList" |
|||
:key="k" |
|||
> |
|||
<!--inco--> |
|||
<view |
|||
class="fui-node" |
|||
:style="{borderColor:(k != tableList.length-1 ? '#29d3b4' :'' ) }" |
|||
> |
|||
</view> |
|||
<template v-slot:right> |
|||
<view |
|||
class="fui-process__node table_itme" |
|||
:style="{paddingBottom:(k !== tableList.length-1 ? '50rpx' :'0rpx')}" |
|||
:class="{'fui-node__pb':k!==tableList.length-1}" |
|||
> |
|||
|
|||
<view class="fui-title"> |
|||
<!--修改时间--> |
|||
{{v.modification_time}} |
|||
</view> |
|||
<view class="itme_box"> |
|||
<view class="title_name">修改人:{{v.staff_id_name}} 修改了如下内容</view> |
|||
<view class="table_section"> |
|||
<table class="table_box"> |
|||
<!-- 自定义表头 --> |
|||
<thead> |
|||
<tr> |
|||
<th style="width: 30%; border: 1px solid #ddd; padding: 12rpx;">字段名称</th> |
|||
<th style="width: 34%; border: 1px solid #ddd; padding: 12rpx;">原数据</th> |
|||
<th style="width: 34%; border: 1px solid #ddd; padding: 12rpx;">新数据</th> |
|||
</tr> |
|||
</thead> |
|||
|
|||
<!-- 自定义每一行数据 --> |
|||
<tbody> |
|||
<tr v-for="(row, index) in v.update_arr" :key="index"> |
|||
<td style="width: 30%; border: 1px solid #ddd; padding: 12rpx;">{{ row.field_name_zh }}</td> |
|||
<td style="width: 34%; border: 1px solid #ddd; padding: 12rpx;">{{ row.old_value }}</td> |
|||
<td style="width: 34%; border: 1px solid #ddd; padding: 12rpx;">{{ row.new_value }}</td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
</fui-timeaxis-node> |
|||
</fui-timeaxis> |
|||
</view> |
|||
</scroll-view> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import apiRoute from '@/api/apiRoute.js'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
|
|||
loading:false,//加载状态 |
|||
lowerThreshold: 100,//距离底部多远触发 |
|||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|||
|
|||
//筛选条件 |
|||
filteredData:{ |
|||
page:1,//当前页码 |
|||
limit:10,//每页返回数据条数 |
|||
total:10,//数据总条数 |
|||
type:'resource',//查询类型|resource=客户资源,six_speed=六要素 |
|||
customer_resource_id: '',//客户资源表id |
|||
}, |
|||
//数据列表 |
|||
tableList:[],//表格数据 |
|||
|
|||
//tab切换 |
|||
optionTableId:0,//分段器初始选中项索引 |
|||
optionTable:[ |
|||
{ |
|||
id: 0, |
|||
name: '客户资源修改记录', |
|||
type:'resource', |
|||
}, |
|||
{ |
|||
id: 1, |
|||
name: '六要素修改记录', |
|||
type:'six_speed', |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
onLoad(options) { |
|||
this.filteredData.customer_resource_id = options.resource_id//客户资源表id |
|||
}, |
|||
onShow() { |
|||
this.init() |
|||
}, |
|||
//下拉刷新 |
|||
async onPullDownRefresh() { |
|||
//重置为第一页 |
|||
await this.resetFilteredData() |
|||
await this.getList() |
|||
}, |
|||
methods: { |
|||
//初始化 |
|||
async init() { |
|||
await this.getList()//获取客户修改记录列表 |
|||
}, |
|||
|
|||
//加载更多(下一页) |
|||
loadMoreData() { |
|||
//判断是否加载 |
|||
if (!this.isReachedBottom) { |
|||
this.isReachedBottom = true;//设置为不可请求状态 |
|||
this.getList(); |
|||
} |
|||
}, |
|||
//重置为第一页 |
|||
async resetFilteredData() { |
|||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|||
|
|||
this.filteredData.page = 1//当前页码 |
|||
this.filteredData.limit = 10//每页返回数据条数 |
|||
this.filteredData.total = 10//数据总条数 |
|||
}, |
|||
//获取列表-客户信息修改记录 |
|||
async getList(){ |
|||
this.loading = true |
|||
|
|||
let data = {...this.filteredData} |
|||
|
|||
//判断是否还有数据 |
|||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|||
this.loading = false |
|||
uni.showToast({ |
|||
title: '暂无更多', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if(data.page == 1){ |
|||
this.tableList = [] |
|||
} |
|||
|
|||
let res = await apiRoute.xs_customerResourcesGetEditLogList(data) |
|||
this.loading = false |
|||
this.isReachedBottom = false; |
|||
if (res.code != 1){ |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
console.log(123123123,res) |
|||
|
|||
this.tableList = this.tableList.concat(res.data.data); // 使用 concat 方法 将新数据追加到数组中 |
|||
|
|||
console.log('列表1',this.tableList) |
|||
this.filteredData.total = res.data.total |
|||
this.filteredData.page++ |
|||
|
|||
}, |
|||
|
|||
//切换tag列表 |
|||
async segmented(e) { |
|||
console.log('切换',e) |
|||
//e.id|0=基础信息 1=六要素 |
|||
let status = e.id |
|||
this.optionTableId = String(status) |
|||
this.filteredData.type = e.type//查询类型|resource=客户资源,six_speed=六要素 |
|||
|
|||
await this.resetFilteredData() |
|||
await this.getList() |
|||
}, |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.assemble{ |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: #292929; |
|||
overflow: auto; |
|||
.tab_section{ |
|||
padding: 0 20rpx; |
|||
padding-top: 30rpx; |
|||
} |
|||
.table_list{ |
|||
color: #fff; |
|||
::v-deep .fui-timeaxis__line{ |
|||
background-color: #fff; |
|||
} |
|||
|
|||
.itme_box { |
|||
margin-top: 30rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 25rpx; |
|||
.title_name{ |
|||
font-size: 28rpx; |
|||
} |
|||
.table_section{ |
|||
.table_box{ |
|||
width: 100%; |
|||
border-collapse: collapse; |
|||
table-layout: fixed; |
|||
tr{ |
|||
display: flex; |
|||
th{} |
|||
td{} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
::v-deep .fui-timeaxis__wrap{ |
|||
|
|||
} |
|||
.fui-node { |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
border-radius: 50%; |
|||
background: #fff; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border: 4px solid #ccc; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.fui-process__node { |
|||
padding-left: 20rpx; |
|||
} |
|||
|
|||
.fui-title { |
|||
font-size: 34rpx; |
|||
line-height: 34rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.fui-descr { |
|||
font-size: 28rpx; |
|||
padding-top: 12rpx; |
|||
color: #7F7F7F; |
|||
} |
|||
|
|||
.fui-time__left { |
|||
font-size: 36rpx; |
|||
line-height: 36rpx; |
|||
text-align: right; |
|||
padding-right: 20rpx; |
|||
} |
|||
|
|||
.fui-node__pbtm { |
|||
padding-bottom: 88rpx; |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
} |
|||
</style> |
|||
File diff suppressed because it is too large
@ -1,343 +0,0 @@ |
|||
<!--市场数据统计页面--> |
|||
<template> |
|||
<view class="main_box" :class="{'has-safe-area': hasSafeArea}"> |
|||
<!--自定义导航栏--> |
|||
<view class="navbar_section"> |
|||
<view class="title">市场数据统计</view> |
|||
</view> |
|||
|
|||
<!-- 顶部筛选 --> |
|||
<view class="filter-section"> |
|||
<view class="filter-item"> |
|||
<view class="label">统计时间:</view> |
|||
<picker mode="date" fields="month" :value="currentDate" @change="dateChange"> |
|||
<view class="picker-value">{{currentDate}}</view> |
|||
</picker> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 市场人员资源量统计 --> |
|||
<view class="table-section"> |
|||
<view class="table-title">市场人员资源量统计</view> |
|||
<view class="table-container"> |
|||
<view class="table-header"> |
|||
<view class="th th-person">人员</view> |
|||
<view class="th th-week">周数量</view> |
|||
<view class="th th-month">月数量</view> |
|||
<view class="th th-year">年数量</view> |
|||
</view> |
|||
<view class="table-body"> |
|||
<view class="table-row" v-for="(item, index) in staffData" :key="index"> |
|||
<view class="td td-person">{{item.name}}</view> |
|||
<view class="td td-week">{{item.weekCount}}</view> |
|||
<view class="td td-month">{{item.monthCount}}</view> |
|||
<view class="td td-year">{{item.yearCount}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 校区人员资源渠道量 --> |
|||
<view class="table-section"> |
|||
<view class="table-title">{{currentMonth}}月 - 年度校区人员资源渠道量</view> |
|||
<view class="table-container"> |
|||
<view class="table-header"> |
|||
<view class="th th-channel" style="width: 100px;">渠道</view> |
|||
<view class="th" v-for="(school, index) in schoolList" :key="index">{{school.campus_name}}</view> |
|||
<view class="th th-total">渠道合计</view> |
|||
</view> |
|||
<view class="table-body"> |
|||
<view class="table-row" v-for="(channel, index) in channelList" :key="index"> |
|||
<view class="td td-channel" style="width: 100px;">{{channel.name}}</view> |
|||
<view class="td" v-for="(school, sIndex) in schoolList" :key="sIndex"> |
|||
{{channel[school.id] || 0}} |
|||
</view> |
|||
<view class="td td-total">{{channel.total}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 市场人员资源渠道统计 --> |
|||
<view class="table-section"> |
|||
<view class="table-title">{{currentMonth}}月 - 年度市场人员资源渠道统计</view> |
|||
<view class="table-container"> |
|||
<view class="table-header"> |
|||
<view class="th th-channel" style="width: 100px;">渠道</view> |
|||
<view class="th" v-for="(staff, index) in staffData" :key="index">市场{{staff.name}}</view> |
|||
<view class="th th-total">资源合计</view> |
|||
</view> |
|||
<view class="table-body"> |
|||
<view class="table-row" v-for="(channel, index) in channelList" :key="index"> |
|||
<view class="td td-channel" style="width: 100px;">{{channel.name}}</view> |
|||
<view class="td" v-for="(staff, sIndex) in staffData" :key="sIndex"> |
|||
{{staff['channel'][channel.value] || 0}} |
|||
</view> |
|||
<view class="td td-total">{{channel.total}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<AQTabber /> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import apiRoute from '@/api/apiRoute.js'; |
|||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|||
|
|||
export default { |
|||
components: { |
|||
AQTabber, |
|||
}, |
|||
data() { |
|||
return { |
|||
currentDate: this.formatDate(new Date()), |
|||
currentMonth: new Date().getMonth() + 1, |
|||
// 市场人员资源量统计 |
|||
staffData: [], |
|||
// 校区列表 |
|||
schoolList: [], |
|||
// 是否有安全区域 |
|||
hasSafeArea: false, |
|||
// 渠道列表 |
|||
channelList: [], |
|||
// 市场人员列表 |
|||
marketStaffList: [ |
|||
{ id: 'A', name: 'A' }, |
|||
{ id: 'B', name: 'B' }, |
|||
{ id: 'C', name: 'C' }, |
|||
{ id: 'D', name: 'D' } |
|||
], |
|||
// 校区渠道数据 |
|||
channelSchoolData: [], |
|||
// 人员渠道数据 |
|||
channelStaffData: [] |
|||
} |
|||
}, |
|||
onLoad() { |
|||
this.initData(); |
|||
this.checkSafeArea(); |
|||
}, |
|||
methods: { |
|||
// 格式化日期为 YYYY-MM |
|||
formatDate(date) { |
|||
const year = date.getFullYear(); |
|||
const month = (date.getMonth() + 1).toString().padStart(2, '0'); |
|||
return `${year}-${month}`; |
|||
}, |
|||
|
|||
// 日期选择器变更 |
|||
dateChange(e) { |
|||
this.currentDate = e.detail.value; |
|||
const [year, month] = this.currentDate.split('-'); |
|||
this.currentMonth = parseInt(month); |
|||
this.initData(); |
|||
}, |
|||
|
|||
// 初始化数据 |
|||
async initData() { |
|||
// 模拟获取数据,实际项目中应该调用API |
|||
await this.getStaffStatistics(); |
|||
// await this.getChannelSchoolStatistics(); |
|||
// this.getChannelStaffStatistics(); |
|||
}, |
|||
|
|||
// 获取人员资源量统计 |
|||
async getStaffStatistics() { |
|||
// 模拟数据,实际项目中应该调用API |
|||
let res = await apiRoute.getStaffStatistics({date: this.currentDate}) |
|||
|
|||
console.log(res.data.staffData,"================"); |
|||
this.staffData = res.data.staffData |
|||
this.schoolList = res.data.schoolList |
|||
this.channelList = res.data.channelList |
|||
|
|||
}, |
|||
|
|||
// 获取校区渠道统计 |
|||
getChannelSchoolStatistics() { |
|||
// 模拟数据,实际项目中应该调用API |
|||
this.channelSchoolData = this.channelList.map(channel => { |
|||
const schools = {}; |
|||
let total = 0; |
|||
|
|||
this.schoolList.forEach(school => { |
|||
const count = Math.floor(Math.random() * 50); |
|||
schools[school.id] = count; |
|||
total += count; |
|||
}); |
|||
|
|||
return { |
|||
id: channel.id, |
|||
name: channel.name, |
|||
schools, |
|||
total |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
// 获取人员渠道统计 |
|||
getChannelStaffStatistics() { |
|||
// 模拟数据,实际项目中应该调用API |
|||
this.channelStaffData = this.channelList.map(channel => { |
|||
const staffs = {}; |
|||
let total = 0; |
|||
|
|||
this.marketStaffList.forEach(staff => { |
|||
const count = Math.floor(Math.random() * 40); |
|||
staffs[staff.id] = count; |
|||
total += count; |
|||
}); |
|||
|
|||
return { |
|||
id: channel.id, |
|||
name: channel.name, |
|||
staffs, |
|||
total |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
// 检测设备是否有安全区域 |
|||
checkSafeArea() { |
|||
try { |
|||
const systemInfo = uni.getSystemInfoSync(); |
|||
// 检测是否为iPhone X及以上机型或其他有安全区域的设备 |
|||
if (systemInfo.safeAreaInsets && systemInfo.safeAreaInsets.bottom > 0) { |
|||
this.hasSafeArea = true; |
|||
} |
|||
} catch (e) { |
|||
console.error('获取系统信息失败', e); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.main_box { |
|||
min-height: 100vh; |
|||
background-color: #1a1a1a; |
|||
color: #ffffff; |
|||
padding-bottom: 150rpx; /* 增加底部内边距,防止内容被底部导航栏遮挡 */ |
|||
} |
|||
|
|||
/* 适配有安全区域的设备(如iPhone X及以上机型) */ |
|||
.has-safe-area { |
|||
padding-bottom: calc(150rpx + constant(safe-area-inset-bottom)); /* iOS 11.0-11.2 */ |
|||
padding-bottom: calc(150rpx + env(safe-area-inset-bottom)); /* iOS 11.2+ */ |
|||
} |
|||
|
|||
.navbar_section { |
|||
background-color: #1a1a1a; |
|||
height: 88rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
position: relative; |
|||
|
|||
.title { |
|||
font-size: 36rpx; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.filter-section { |
|||
padding: 20rpx; |
|||
background-color: #222222; |
|||
margin: 20rpx; |
|||
border-radius: 10rpx; |
|||
|
|||
.filter-item { |
|||
display: flex; |
|||
align-items: center; |
|||
|
|||
.label { |
|||
font-size: 28rpx; |
|||
margin-right: 10rpx; |
|||
} |
|||
|
|||
.picker-value { |
|||
padding: 10rpx 20rpx; |
|||
background-color: #333333; |
|||
border-radius: 6rpx; |
|||
font-size: 28rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.table-section { |
|||
margin: 30rpx 20rpx; |
|||
background-color: #222222; |
|||
border-radius: 10rpx; |
|||
overflow: hidden; |
|||
|
|||
.table-title { |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
padding: 20rpx; |
|||
border-bottom: 1px solid #333333; |
|||
} |
|||
|
|||
.table-container { |
|||
width: 100%; |
|||
overflow-x: auto; |
|||
} |
|||
|
|||
.table-header { |
|||
display: flex; |
|||
background-color: #333333; |
|||
|
|||
.th { |
|||
padding: 15rpx 10rpx; |
|||
font-size: 26rpx; |
|||
text-align: center; |
|||
flex: 1; |
|||
min-width: 100rpx; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
.table-body { |
|||
.table-row { |
|||
display: flex; |
|||
border-bottom: 1px solid #333333; |
|||
|
|||
&:last-child { |
|||
border-bottom: none; |
|||
} |
|||
|
|||
.td { |
|||
padding: 15rpx 10rpx; |
|||
font-size: 26rpx; |
|||
text-align: center; |
|||
flex: 1; |
|||
min-width: 100rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.th-person, .td-person { |
|||
min-width: 80rpx; |
|||
flex: 0.8; |
|||
} |
|||
|
|||
.th-week, .td-week, |
|||
.th-month, .td-month, |
|||
.th-year, .td-year { |
|||
flex: 1; |
|||
} |
|||
|
|||
.th-channel, .td-channel { |
|||
flex: 1.2; |
|||
text-align: left; |
|||
padding-left: 20rpx; |
|||
} |
|||
|
|||
.th-total, .td-total { |
|||
flex: 1.2; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,427 +0,0 @@ |
|||
<template> |
|||
<view class="assemble"> |
|||
<view style="height: 20rpx;"></view> |
|||
<!-- 时间筛选 --> |
|||
<view class="filter-section"> |
|||
<picker mode="date" fields="month" :value="currentDate" @change="onDateChange"> |
|||
<view class="date-picker"> |
|||
<text>{{currentDate}}</text> |
|||
<image class="drop-image" :src="$util.img('/static/images/drop.png')" mode="aspectFit"></image> |
|||
</view> |
|||
</picker> |
|||
</view> |
|||
|
|||
<!-- 本月提成卡片 --> |
|||
<view class="commission-card"> |
|||
<view class="card-title">本月提成</view> |
|||
<view class="commission-amount">¥{{totalCommission}}</view> |
|||
</view> |
|||
|
|||
<!-- 续费提成记录 --> |
|||
<view class="record-card"> |
|||
<view class="card-title">续费提成</view> |
|||
<view class="table"> |
|||
<view class="table-header"> |
|||
<view class="th">时间</view> |
|||
<view class="th">到期数</view> |
|||
<view class="th">续费数</view> |
|||
<view class="th">续费率</view> |
|||
<view class="th">提成</view> |
|||
</view> |
|||
<view class="table-body"> |
|||
<view class="tr" v-for="(item, index) in renewalRecords" :key="index"> |
|||
<view class="td">{{item.time}}</view> |
|||
<view class="td">{{item.expireCount}}</view> |
|||
<view class="td">{{item.renewCount}}</view> |
|||
<view class="td">{{item.renewRate}}%</view> |
|||
<view class="td">¥{{item.commission}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 新招课包 --> |
|||
<view class="record-card"> |
|||
<view class="card-title">新招课包</view> |
|||
<view class="table"> |
|||
<view class="table-header"> |
|||
<view class="th">成交数</view> |
|||
<view class="th">提成</view> |
|||
<view class="th">合计</view> |
|||
</view> |
|||
<view class="table-body"> |
|||
<view class="tr"> |
|||
<view class="td">{{newPackageCount}}</view> |
|||
<view class="td">¥{{newPackageCommission}}</view> |
|||
<view class="td">¥{{newPackageTotal}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 私教课包 --> |
|||
<view class="record-card"> |
|||
<view class="card-title">私教课包</view> |
|||
<view class="table"> |
|||
<view class="table-header"> |
|||
<view class="th">数量</view> |
|||
<view class="th">提成</view> |
|||
</view> |
|||
<view class="table-body"> |
|||
<view class="tr"> |
|||
<view class="td">{{privatePackageCount}}</view> |
|||
<view class="td">¥{{privatePackageCommission}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 时间卡 --> |
|||
<view class="record-card"> |
|||
<view class="card-title">时间卡</view> |
|||
<view class="table"> |
|||
<view class="table-header"> |
|||
<view class="th">时间卡</view> |
|||
<view class="th">数量</view> |
|||
<view class="th">提成</view> |
|||
</view> |
|||
<view class="table-body"> |
|||
<view class="tr"> |
|||
<view class="td">{{timeCardCount}}</view> |
|||
<view class="td">{{timeCardAmount}}</view> |
|||
<view class="td">¥{{timeCardCommission}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 其他提成 --> |
|||
<view class="record-card"> |
|||
<view class="card-title">其他提成</view> |
|||
<view class="table"> |
|||
<view class="table-header"> |
|||
<view class="th">项目</view> |
|||
<view class="th">金额</view> |
|||
</view> |
|||
<view class="table-body"> |
|||
<view class="tr" v-for="(item, index) in otherCommissions" :key="index"> |
|||
<view class="td">{{item.project}}</view> |
|||
<view class="td">¥{{item.amount}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import apiRoute from '@/api/apiRoute.js' |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
currentDate: this.formatDate(new Date()), |
|||
totalCommission: 0, |
|||
renewalRecords: [], |
|||
newPackageCount: 0, |
|||
newPackageCommission: 0, |
|||
newPackageTotal: 0, |
|||
privatePackageCount: 0, |
|||
privatePackageCommission: 0, |
|||
timeCardCount: 0, |
|||
timeCardAmount: 0, |
|||
timeCardCommission: 0, |
|||
otherCommissions: [] |
|||
} |
|||
}, |
|||
onShow() { |
|||
this.getStatisticsData() |
|||
}, |
|||
methods: { |
|||
formatDate(date) { |
|||
const year = date.getFullYear() |
|||
const month = String(date.getMonth() + 1).padStart(2, '0') |
|||
return `${year}-${month}` |
|||
}, |
|||
onDateChange(e) { |
|||
this.currentDate = e.detail.value |
|||
this.getStatisticsData() |
|||
}, |
|||
async getStatisticsData() { |
|||
try { |
|||
const res = await apiRoute.xs_statisticsMarketData({ |
|||
date: this.currentDate |
|||
}) |
|||
if (res && res.code === 1) { |
|||
const data = res.data |
|||
this.totalCommission = data.totalCommission || 0 |
|||
this.renewalRecords = data.renewalRecords || [] |
|||
this.newPackageCount = data.newPackageCount || 0 |
|||
this.newPackageCommission = data.newPackageCommission || 0 |
|||
this.newPackageTotal = data.newPackageTotal || 0 |
|||
this.privatePackageCount = data.privatePackageCount || 0 |
|||
this.privatePackageCommission = data.privatePackageCommission || 0 |
|||
this.timeCardCount = data.timeCardCount || 0 |
|||
this.timeCardAmount = data.timeCardAmount || 0 |
|||
this.timeCardCommission = data.timeCardCommission || 0 |
|||
this.otherCommissions = data.otherCommissions || [] |
|||
} |
|||
} catch (error) { |
|||
console.error('获取统计数据失败:', error) |
|||
uni.showToast({ |
|||
title: '获取数据失败', |
|||
icon: 'none' |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
//自定义导航栏 |
|||
.navbar_section { |
|||
border: 1px solid #23262F; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
background: #23262F; |
|||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.18); |
|||
|
|||
.title { |
|||
padding: 40rpx 0rpx; |
|||
// #ifdef MP-WEIXIN |
|||
padding: 80rpx 0rpx; |
|||
// #endif |
|||
font-size: 30rpx; |
|||
color: #F5F6FA; |
|||
font-weight: bold; |
|||
letter-spacing: 2rpx; |
|||
} |
|||
} |
|||
|
|||
.assemble { |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
background: #181A20; |
|||
padding-bottom: 100rpx; |
|||
} |
|||
|
|||
.div-style { |
|||
width: 92%; |
|||
height: 85vh; |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
margin: auto; |
|||
} |
|||
|
|||
.coach-message { |
|||
width: 92%; |
|||
margin: 10rpx auto; |
|||
display: flex; |
|||
align-items: center; |
|||
padding-top: 20rpx; |
|||
} |
|||
|
|||
.drop-image { |
|||
width: 50rpx; |
|||
height: 50rpx; |
|||
filter: brightness(0.8); |
|||
} |
|||
|
|||
.title { |
|||
font-size: 30rpx; |
|||
color: #F5F6FA; |
|||
padding-left: 20rpx; |
|||
} |
|||
|
|||
.left1 { |
|||
width: 48%; |
|||
height: 95%; |
|||
margin: auto; |
|||
} |
|||
|
|||
.right1 { |
|||
width: 48%; |
|||
height: 95%; |
|||
margin: auto; |
|||
|
|||
.statistics_box { |
|||
margin: auto; |
|||
margin-top: 10rpx; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
|
|||
.item { |
|||
width: 90rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
|
|||
.box { |
|||
width: 100%; |
|||
height: 328rpx; |
|||
border: 1px solid #ddd; |
|||
border-radius: 6rpx; |
|||
background: #f5f5f5; |
|||
position: relative; |
|||
|
|||
.progress-bar { |
|||
width: 100%; |
|||
height: 0; |
|||
transition: height 0.3s ease; |
|||
position: absolute; |
|||
bottom: 0; |
|||
} |
|||
|
|||
.ratio { |
|||
width: 100%; |
|||
position: absolute; |
|||
bottom: -0rpx; |
|||
font-size: 26rpx; |
|||
text-align: center; |
|||
} |
|||
} |
|||
|
|||
.title { |
|||
margin-top: 5rpx; |
|||
padding: 0; |
|||
font-size: 26rpx; |
|||
color: #999999; |
|||
; |
|||
text-align: center; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.this_month { |
|||
width: 100%; |
|||
height: 95%; |
|||
margin: auto; |
|||
} |
|||
|
|||
.drop-image-x { |
|||
width: 20rpx; |
|||
height: 20rpx; |
|||
} |
|||
|
|||
.title-x { |
|||
font-size: 28rpx; |
|||
color: #7F7F7F; |
|||
padding-left: 20rpx; |
|||
} |
|||
|
|||
.title-x1 { |
|||
font-size: 28rpx; |
|||
color: #333333; |
|||
padding-left: 60rpx; |
|||
} |
|||
|
|||
.filter-section { |
|||
padding: 20rpx 30rpx; |
|||
background: #23262F; |
|||
margin-bottom: 20rpx; |
|||
border-radius: 12rpx; |
|||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.2); |
|||
|
|||
.date-picker { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 32rpx; |
|||
color: #F5F6FA; |
|||
|
|||
.drop-image { |
|||
width: 30rpx; |
|||
height: 30rpx; |
|||
margin-left: 10rpx; |
|||
filter: brightness(0.8); |
|||
} |
|||
} |
|||
} |
|||
|
|||
.commission-card { |
|||
background: linear-gradient(135deg, #FF6B6B, #FF8E8E); |
|||
margin: 20rpx; |
|||
padding: 30rpx; |
|||
border-radius: 16rpx; |
|||
color: #fff; |
|||
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.25); |
|||
|
|||
.card-title { |
|||
font-size: 28rpx; |
|||
margin-bottom: 20rpx; |
|||
color: #fff; |
|||
} |
|||
|
|||
.commission-amount { |
|||
font-size: 48rpx; |
|||
font-weight: bold; |
|||
color: #fff; |
|||
} |
|||
} |
|||
|
|||
.record-card { |
|||
background: #23262F; |
|||
margin: 20rpx; |
|||
padding: 20rpx; |
|||
border-radius: 16rpx; |
|||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.18); |
|||
|
|||
.card-title { |
|||
font-size: 30rpx; |
|||
color: #F5F6FA; |
|||
margin-bottom: 20rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.table { |
|||
width: 100%; |
|||
|
|||
.table-header { |
|||
display: flex; |
|||
background: #181A20; |
|||
padding: 20rpx 0; |
|||
border-radius: 8rpx 8rpx 0 0; |
|||
|
|||
.th { |
|||
flex: 1; |
|||
text-align: center; |
|||
font-size: 26rpx; |
|||
color: #A0A3B1; |
|||
font-weight: 500; |
|||
} |
|||
} |
|||
|
|||
.table-body { |
|||
.tr { |
|||
display: flex; |
|||
padding: 20rpx 0; |
|||
border-bottom: 1px solid #33343A; |
|||
transition: background 0.2s; |
|||
|
|||
&:last-child { |
|||
border-bottom: none; |
|||
} |
|||
|
|||
.td { |
|||
flex: 1; |
|||
text-align: center; |
|||
font-size: 26rpx; |
|||
color: #F5F6FA; |
|||
font-weight: 400; |
|||
} |
|||
&:hover { |
|||
background: #23262F; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 其他细节样式 |
|||
::-webkit-scrollbar { |
|||
display: none; |
|||
} |
|||
</style> |
|||
@ -1,495 +0,0 @@ |
|||
<!--校区数据--> |
|||
<template> |
|||
<view class="main_box"> |
|||
<!--自定义导航栏--> |
|||
<view class="navbar_section"> |
|||
<view class="navbar_content"> |
|||
<view class="back_btn" @click="goBack"> |
|||
<fui-icon name="arrowleft" size="32" color="#fff"></fui-icon> |
|||
</view> |
|||
<view class="title">校区数据</view> |
|||
<view class="placeholder"></view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="content_section"> |
|||
<!-- 校区选择器 --> |
|||
<view class="campus_selector"> |
|||
<view class="selector_label">选择校区:</view> |
|||
<view class="selector_box"> |
|||
<view class="selected_campus">请选择校区</view> |
|||
<fui-icon name="dropdown" size="24" color="#999"></fui-icon> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 数据概览卡片 --> |
|||
<view class="overview_cards"> |
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="home" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">部门数量</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="addressbook" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">员工总数</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="star" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">客户总数</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="wallet" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">校区业绩</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 部门对比 --> |
|||
<view class="dept_comparison"> |
|||
<view class="section_title">部门业绩对比</view> |
|||
<view class="comparison_list"> |
|||
<view class="comparison_item"> |
|||
<view class="dept_info"> |
|||
<view class="dept_name">销售部</view> |
|||
<view class="dept_score">¥120000</view> |
|||
</view> |
|||
<view class="progress_bar"> |
|||
<view class="progress_fill" style="width: 80%"></view> |
|||
</view> |
|||
<view class="dept_percent">80%</view> |
|||
</view> |
|||
|
|||
<view class="comparison_item"> |
|||
<view class="dept_info"> |
|||
<view class="dept_name">市场部</view> |
|||
<view class="dept_score">¥100000</view> |
|||
</view> |
|||
<view class="progress_bar"> |
|||
<view class="progress_fill" style="width: 67%"></view> |
|||
</view> |
|||
<view class="dept_percent">67%</view> |
|||
</view> |
|||
|
|||
<view class="comparison_item"> |
|||
<view class="dept_info"> |
|||
<view class="dept_name">运营部</view> |
|||
<view class="dept_score">¥80000</view> |
|||
</view> |
|||
<view class="progress_bar"> |
|||
<view class="progress_fill" style="width: 53%"></view> |
|||
</view> |
|||
<view class="dept_percent">53%</view> |
|||
</view> |
|||
|
|||
<view class="comparison_item"> |
|||
<view class="dept_info"> |
|||
<view class="dept_name">客服部</view> |
|||
<view class="dept_score">¥60000</view> |
|||
</view> |
|||
<view class="progress_bar"> |
|||
<view class="progress_fill" style="width: 40%"></view> |
|||
</view> |
|||
<view class="dept_percent">40%</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 月度趋势 --> |
|||
<view class="trend_section"> |
|||
<view class="section_title">月度趋势</view> |
|||
<view class="trend_chart"> |
|||
<view class="chart_placeholder"> |
|||
<fui-icon name="linechart" size="80" color="#ddd"></fui-icon> |
|||
<view class="placeholder_text">图表功能待开发</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 功能按钮区域 --> |
|||
<view class="function_section"> |
|||
<view class="section_title">数据分析</view> |
|||
<view class="function_grid"> |
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="barchart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">校区对比</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="piechart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">部门分析</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="linechart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">趋势分析</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="list" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">详细报表</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 提示信息 --> |
|||
<view class="tips_section"> |
|||
<view class="tips_title">功能说明</view> |
|||
<view class="tips_content"> |
|||
这里将显示校区的各项数据统计,包括部门数量、员工总数、客户数量、校区业绩等。 |
|||
具体功能待后续开发实现。 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import fuiIcon from "@/components/firstui/fui-icon/fui-icon.vue" |
|||
|
|||
export default { |
|||
components: { |
|||
fuiIcon, |
|||
}, |
|||
data() { |
|||
return { |
|||
|
|||
} |
|||
}, |
|||
onLoad() { |
|||
|
|||
}, |
|||
methods: { |
|||
// 返回上一页 |
|||
goBack() { |
|||
uni.navigateBack() |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.main_box { |
|||
background: #f5f5f5; |
|||
min-height: 100vh; |
|||
} |
|||
|
|||
// 自定义导航栏 |
|||
.navbar_section { |
|||
background: #29D3B4; |
|||
padding-top: 20rpx; |
|||
|
|||
// 小程序端样式 |
|||
// #ifdef MP-WEIXIN |
|||
padding-top: 90rpx; |
|||
// #endif |
|||
|
|||
.navbar_content { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 20rpx 24rpx 40rpx 24rpx; |
|||
|
|||
.back_btn { |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.title { |
|||
font-size: 32rpx; |
|||
color: #fff; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.placeholder { |
|||
width: 60rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 内容区域 |
|||
.content_section { |
|||
padding: 40rpx 24rpx; |
|||
|
|||
// 校区选择器 |
|||
.campus_selector { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
margin-bottom: 32rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.selector_label { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
margin-bottom: 16rpx; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.selector_box { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 20rpx 24rpx; |
|||
background: #f8f8f8; |
|||
border-radius: 12rpx; |
|||
|
|||
.selected_campus { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 概览卡片 |
|||
.overview_cards { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
gap: 24rpx; |
|||
margin-bottom: 40rpx; |
|||
|
|||
.card_item { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 20rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.card_icon { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
background: rgba(41, 211, 180, 0.1); |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.card_content { |
|||
flex: 1; |
|||
|
|||
.card_title { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
margin-bottom: 8rpx; |
|||
} |
|||
|
|||
.card_value { |
|||
font-size: 32rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 部门对比 |
|||
.dept_comparison { |
|||
margin-bottom: 40rpx; |
|||
|
|||
.section_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.comparison_list { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.comparison_item { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 32rpx; |
|||
|
|||
&:last-child { |
|||
margin-bottom: 0; |
|||
} |
|||
|
|||
.dept_info { |
|||
width: 150rpx; |
|||
|
|||
.dept_name { |
|||
font-size: 26rpx; |
|||
color: #333; |
|||
margin-bottom: 8rpx; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.dept_score { |
|||
font-size: 22rpx; |
|||
color: #29D3B4; |
|||
font-weight: 600; |
|||
} |
|||
} |
|||
|
|||
.progress_bar { |
|||
flex: 1; |
|||
height: 16rpx; |
|||
background: #f0f0f0; |
|||
border-radius: 8rpx; |
|||
margin: 0 20rpx; |
|||
overflow: hidden; |
|||
|
|||
.progress_fill { |
|||
height: 100%; |
|||
background: linear-gradient(90deg, #29D3B4, #5CE1E6); |
|||
border-radius: 8rpx; |
|||
transition: width 0.3s ease; |
|||
} |
|||
} |
|||
|
|||
.dept_percent { |
|||
width: 60rpx; |
|||
text-align: right; |
|||
font-size: 24rpx; |
|||
color: #29D3B4; |
|||
font-weight: 600; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 月度趋势 |
|||
.trend_section { |
|||
margin-bottom: 40rpx; |
|||
|
|||
.section_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.trend_chart { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 40rpx 24rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.chart_placeholder { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 200rpx; |
|||
|
|||
.placeholder_text { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
margin-top: 16rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 功能区域 |
|||
.function_section { |
|||
margin-bottom: 40rpx; |
|||
|
|||
.section_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.function_grid { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
gap: 32rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.function_item { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
padding: 24rpx 16rpx; |
|||
border-radius: 12rpx; |
|||
transition: all 0.3s ease; |
|||
|
|||
&:active { |
|||
background-color: #f5f5f5; |
|||
transform: scale(0.95); |
|||
} |
|||
|
|||
.function_icon { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
background: rgba(41, 211, 180, 0.1); |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.function_text { |
|||
font-size: 24rpx; |
|||
color: #333; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 提示信息 |
|||
.tips_section { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.tips_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.tips_content { |
|||
font-size: 24rpx; |
|||
color: #666; |
|||
line-height: 1.6; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,445 +0,0 @@ |
|||
<!--部门数据--> |
|||
<template> |
|||
<view class="main_box"> |
|||
<!--自定义导航栏--> |
|||
<view class="navbar_section"> |
|||
<view class="navbar_content"> |
|||
<view class="back_btn" @click="goBack"> |
|||
<fui-icon name="arrowleft" size="32" color="#fff"></fui-icon> |
|||
</view> |
|||
<view class="title">部门数据</view> |
|||
<view class="placeholder"></view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="content_section"> |
|||
<!-- 部门选择器 --> |
|||
<view class="dept_selector"> |
|||
<view class="selector_label">选择部门:</view> |
|||
<view class="selector_box"> |
|||
<view class="selected_dept">请选择部门</view> |
|||
<fui-icon name="dropdown" size="24" color="#999"></fui-icon> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 数据概览卡片 --> |
|||
<view class="overview_cards"> |
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="addressbook" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">部门人数</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="star" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">总客户数</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="wallet" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">部门业绩</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="check" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">完成率</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 排行榜 --> |
|||
<view class="ranking_section"> |
|||
<view class="section_title">部门排行榜</view> |
|||
<view class="ranking_list"> |
|||
<view class="ranking_item"> |
|||
<view class="rank_number first">1</view> |
|||
<view class="member_info"> |
|||
<view class="member_name">张三</view> |
|||
<view class="member_score">业绩:¥50000</view> |
|||
</view> |
|||
<view class="medal"> |
|||
<fui-icon name="star-fill" size="24" color="#FFD700"></fui-icon> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="ranking_item"> |
|||
<view class="rank_number second">2</view> |
|||
<view class="member_info"> |
|||
<view class="member_name">李四</view> |
|||
<view class="member_score">业绩:¥45000</view> |
|||
</view> |
|||
<view class="medal"> |
|||
<fui-icon name="star-fill" size="24" color="#C0C0C0"></fui-icon> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="ranking_item"> |
|||
<view class="rank_number third">3</view> |
|||
<view class="member_info"> |
|||
<view class="member_name">王五</view> |
|||
<view class="member_score">业绩:¥40000</view> |
|||
</view> |
|||
<view class="medal"> |
|||
<fui-icon name="star-fill" size="24" color="#CD7F32"></fui-icon> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 功能按钮区域 --> |
|||
<view class="function_section"> |
|||
<view class="section_title">数据分析</view> |
|||
<view class="function_grid"> |
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="barchart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">业绩对比</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="piechart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">人员分布</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="linechart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">趋势分析</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="list" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">详细报表</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 提示信息 --> |
|||
<view class="tips_section"> |
|||
<view class="tips_title">功能说明</view> |
|||
<view class="tips_content"> |
|||
这里将显示部门的各项数据统计,包括部门人员、客户数量、销售业绩、排行榜等。 |
|||
具体功能待后续开发实现。 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import fuiIcon from "@/components/firstui/fui-icon/fui-icon.vue" |
|||
|
|||
export default { |
|||
components: { |
|||
fuiIcon, |
|||
}, |
|||
data() { |
|||
return { |
|||
|
|||
} |
|||
}, |
|||
onLoad() { |
|||
|
|||
}, |
|||
methods: { |
|||
// 返回上一页 |
|||
goBack() { |
|||
uni.navigateBack() |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.main_box { |
|||
background: #f5f5f5; |
|||
min-height: 100vh; |
|||
} |
|||
|
|||
// 自定义导航栏 |
|||
.navbar_section { |
|||
background: #29D3B4; |
|||
padding-top: 20rpx; |
|||
|
|||
// 小程序端样式 |
|||
// #ifdef MP-WEIXIN |
|||
padding-top: 90rpx; |
|||
// #endif |
|||
|
|||
.navbar_content { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 20rpx 24rpx 40rpx 24rpx; |
|||
|
|||
.back_btn { |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.title { |
|||
font-size: 32rpx; |
|||
color: #fff; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.placeholder { |
|||
width: 60rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 内容区域 |
|||
.content_section { |
|||
padding: 40rpx 24rpx; |
|||
|
|||
// 部门选择器 |
|||
.dept_selector { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
margin-bottom: 32rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.selector_label { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
margin-bottom: 16rpx; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.selector_box { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 20rpx 24rpx; |
|||
background: #f8f8f8; |
|||
border-radius: 12rpx; |
|||
|
|||
.selected_dept { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 概览卡片 |
|||
.overview_cards { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
gap: 24rpx; |
|||
margin-bottom: 40rpx; |
|||
|
|||
.card_item { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 20rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.card_icon { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
background: rgba(41, 211, 180, 0.1); |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.card_content { |
|||
flex: 1; |
|||
|
|||
.card_title { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
margin-bottom: 8rpx; |
|||
} |
|||
|
|||
.card_value { |
|||
font-size: 32rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 排行榜 |
|||
.ranking_section { |
|||
margin-bottom: 40rpx; |
|||
|
|||
.section_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.ranking_list { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 24rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.ranking_item { |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 20rpx 16rpx; |
|||
border-bottom: 1px solid #f0f0f0; |
|||
|
|||
&:last-child { |
|||
border-bottom: none; |
|||
} |
|||
|
|||
.rank_number { |
|||
width: 48rpx; |
|||
height: 48rpx; |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 24rpx; |
|||
font-weight: 600; |
|||
color: #fff; |
|||
margin-right: 24rpx; |
|||
|
|||
&.first { |
|||
background: #FFD700; |
|||
} |
|||
|
|||
&.second { |
|||
background: #C0C0C0; |
|||
} |
|||
|
|||
&.third { |
|||
background: #CD7F32; |
|||
} |
|||
} |
|||
|
|||
.member_info { |
|||
flex: 1; |
|||
|
|||
.member_name { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
margin-bottom: 8rpx; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.member_score { |
|||
font-size: 24rpx; |
|||
color: #666; |
|||
} |
|||
} |
|||
|
|||
.medal { |
|||
margin-left: 16rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 功能区域 |
|||
.function_section { |
|||
margin-bottom: 40rpx; |
|||
|
|||
.section_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.function_grid { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
gap: 32rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.function_item { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
padding: 24rpx 16rpx; |
|||
border-radius: 12rpx; |
|||
transition: all 0.3s ease; |
|||
|
|||
&:active { |
|||
background-color: #f5f5f5; |
|||
transform: scale(0.95); |
|||
} |
|||
|
|||
.function_icon { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
background: rgba(41, 211, 180, 0.1); |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.function_text { |
|||
font-size: 24rpx; |
|||
color: #333; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 提示信息 |
|||
.tips_section { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.tips_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.tips_content { |
|||
font-size: 24rpx; |
|||
color: #666; |
|||
line-height: 1.6; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,523 +0,0 @@ |
|||
<!--销售我的-首页--> |
|||
<template> |
|||
<view class="main_box"> |
|||
<!--自定义导航栏--> |
|||
<view class="navbar_section"> |
|||
<view class="title">我的</view> |
|||
</view> |
|||
|
|||
<view style="background:#29D3B4;"> |
|||
<!--用户信息--> |
|||
<view class="user_section"> |
|||
<view class="box"> |
|||
<view class="left" @click="openViewMyInfo()"> |
|||
<image class="pic" :src="userInfo.head_img"></image> |
|||
<view class="name">{{userInfo.name}}</view> |
|||
</view> |
|||
<view class="right"> |
|||
<view class="btn"></view> |
|||
<!-- <view class="btn">切换身份</view>--> |
|||
<view class="btn"></view> |
|||
</view> |
|||
</view> |
|||
<view class="bottom" v-for="(v,k) in userInfo.cameus_dept_arr"> |
|||
<view class="left"> |
|||
<view class="title">校区:</view> |
|||
<view class="title">{{v.campus_id_name || ''}}</view> |
|||
</view> |
|||
<view class="division"></view> |
|||
<view class="right"> |
|||
<view class="title">部门:</view> |
|||
<view class="title dept">{{v.dept_name_str || ''}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
|
|||
|
|||
<view class="main_section"> |
|||
<view class="grid_container"> |
|||
<view class="grid_item" @click="openViewReimbursementList()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="bankcard" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">报销记录</view> |
|||
</view> |
|||
|
|||
<view class="grid_item" @click="openViewMyAttendance()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="calendar" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">我的考勤</view> |
|||
</view> |
|||
|
|||
<view class="grid_item" @click="goCourseSchedule()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="list" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">课程安排</view> |
|||
</view> |
|||
|
|||
<view class="grid_item" @click="openViewMyMessage()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="message" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">我的消息</view> |
|||
</view> |
|||
|
|||
<view class="grid_item" @click="my_contract()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="order" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">我的合同</view> |
|||
</view> |
|||
|
|||
<view class="grid_item" @click="openMyData()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="barchart" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">我的数据</view> |
|||
</view> |
|||
|
|||
<view class="grid_item" @click="openDeptData()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="piechart" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">部门数据</view> |
|||
</view> |
|||
|
|||
<view class="grid_item" @click="openCampusData()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="linechart" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">校区数据</view> |
|||
</view> |
|||
|
|||
<view class="grid_item" @click="openViewSetUp()"> |
|||
<view class="icon_wrapper"> |
|||
<fui-icon name="setup" size="48" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="item_text">设置</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 底部导航--> |
|||
<AQTabber/> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import marketApi from '@/api/market.js'; |
|||
import apiRoute from '@/api/apiRoute.js'; |
|||
import { |
|||
Api_url |
|||
} from "@/common/config.js"; |
|||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|||
import fuiIcon from "@/components/firstui/fui-icon/fui-icon.vue" |
|||
|
|||
|
|||
export default { |
|||
components: { |
|||
AQTabber, |
|||
fuiIcon, |
|||
}, |
|||
data() { |
|||
return { |
|||
formData:{}, |
|||
userInfo:{},//用户信息 |
|||
//上传图片APi路径 |
|||
uploadUrl: `${Api_url}/file/image`, |
|||
|
|||
signedClientListCount:0,//已签客户数量 |
|||
} |
|||
}, |
|||
onLoad() { |
|||
}, |
|||
onShow() { |
|||
this.init(); |
|||
}, |
|||
methods: { |
|||
|
|||
//初始化 |
|||
async init(){ |
|||
await this.getUserInfo()//获取用户详情 |
|||
// await this.getSignedClientListCount()//获取已签客户数量 |
|||
}, |
|||
|
|||
//获取已签客户数量 |
|||
async getSignedClientListCount(){ |
|||
let data = { |
|||
page:1, |
|||
limit:1, |
|||
} |
|||
let res = await marketApi.signClient(data); |
|||
if (res.code != 1){ |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
this.signedClientListCount = res.data.total |
|||
}, |
|||
|
|||
//获取用户详情 |
|||
async getUserInfo(){ |
|||
let data = {} |
|||
let res = await apiRoute.getPersonnelInfo(data); |
|||
if (res.code != 1){ |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
res.data.cameus_dept_arr.forEach((v,k)=>{ |
|||
let d_arr = [] |
|||
v.dept_arr.forEach((dv,dk)=>{ |
|||
d_arr.push(dv.dept_name) |
|||
}) |
|||
//数组转字符串 |
|||
v.dept_name_str = d_arr.join(',') |
|||
}) |
|||
|
|||
this.userInfo = res.data |
|||
}, |
|||
|
|||
|
|||
//打开到课率统计 |
|||
openViewArrivalStatistics(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/arrival_statistics' |
|||
}) |
|||
}, |
|||
|
|||
//打开即将到期 |
|||
openViewDueSoon(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/due_soon' |
|||
}) |
|||
}, |
|||
|
|||
//打开授课统计 |
|||
openViewSchoolingStatistics(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/schooling_statistics' |
|||
}) |
|||
}, |
|||
|
|||
//打开意见反馈 |
|||
openViewFeedback(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-common/feedback' |
|||
}) |
|||
}, |
|||
|
|||
//打开个人资料 |
|||
openViewMyInfo(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/info' |
|||
}) |
|||
}, |
|||
|
|||
|
|||
//跳转页面-已签客户 |
|||
openViewSignedClientList(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/signed_client_list' |
|||
}) |
|||
}, |
|||
|
|||
//跳转页面-我的考勤 |
|||
openViewMyAttendance(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-common/my_attendance' |
|||
}) |
|||
}, |
|||
|
|||
|
|||
//打开企业信息 |
|||
openViewFirmInfo(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/firm_info' |
|||
}) |
|||
}, |
|||
|
|||
|
|||
//打开设置 |
|||
openViewSetUp(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/set_up' |
|||
}) |
|||
}, |
|||
|
|||
//跳转页面-我的消息 |
|||
openViewMyMessage(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-common/my_message' |
|||
}) |
|||
}, |
|||
|
|||
//跳转页面-报销记录 |
|||
openViewReimbursementList(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/reimbursement/list' |
|||
}) |
|||
}, |
|||
|
|||
|
|||
goCourseSchedule(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-coach/coach/schedule/schedule_table' |
|||
}) |
|||
}, |
|||
my_contract(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-common/contract/my_contract' |
|||
}) |
|||
}, |
|||
|
|||
//打开我的数据 |
|||
openMyData(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/my_data' |
|||
}) |
|||
}, |
|||
|
|||
//打开部门数据 |
|||
openDeptData(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/dept_data' |
|||
}) |
|||
}, |
|||
|
|||
//打开校区数据 |
|||
openCampusData(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/campus_data' |
|||
}) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
|
|||
.main_box{ |
|||
background: #292929; |
|||
//min-height: 28vh; |
|||
min-height: 100%; |
|||
} |
|||
|
|||
//自定义导航栏 |
|||
.navbar_section{ |
|||
border: 1px solid #29D3B4; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
background: #29D3B4; |
|||
.title{ |
|||
padding: 40rpx 0rpx; |
|||
|
|||
/* 小程序端样式 */ |
|||
// #ifdef MP-WEIXIN |
|||
padding-top: 110rpx; |
|||
padding-bottom: 40rpx; |
|||
// #endif |
|||
|
|||
font-size: 30rpx; |
|||
color: #fff; |
|||
} |
|||
} |
|||
|
|||
//用户信息 |
|||
.user_section { |
|||
background-color: #29D3B4; |
|||
padding-top: 10rpx; |
|||
padding-bottom: 42rpx; |
|||
color: #fff; |
|||
font-size: 28rpx; |
|||
.box{ |
|||
padding-left: 19rpx; |
|||
padding-right: 29rpx; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
gap: 15rpx; |
|||
.left{ |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 20rpx; |
|||
.pic{ |
|||
width: 144rpx; |
|||
height: 144rpx; |
|||
border-radius: 50%; |
|||
} |
|||
.name{ |
|||
font-size: 28rpx; |
|||
} |
|||
} |
|||
.right{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 20rpx; |
|||
.btn{ |
|||
min-height: 28rpx; |
|||
font-size: 28rpx; |
|||
} |
|||
} |
|||
} |
|||
.bottom{ |
|||
margin-top: 30rpx; |
|||
padding: 0rpx 40rpx; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: flex-start; |
|||
.title{ |
|||
font-size: 28rpx; |
|||
} |
|||
//分割线段 |
|||
.division{ |
|||
width: 2px; |
|||
height: 35rpx; |
|||
background-color: #fff; |
|||
} |
|||
.left{ |
|||
width: 48%; |
|||
display: flex; |
|||
} |
|||
.right{ |
|||
width: 48%; |
|||
display: flex; |
|||
.dept{ |
|||
width: 70%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
//统计信息 |
|||
.count_section{ |
|||
position: relative; |
|||
.main{ |
|||
position: relative; |
|||
z-index: 2; |
|||
padding: 0rpx 24rpx; |
|||
display: flex; |
|||
justify-content: center; |
|||
.course_box{ |
|||
padding: 42rpx 28rpx; |
|||
width: 692rpx; |
|||
border-radius: 20rpx; |
|||
background-color: #fff; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 32rpx; |
|||
.top{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
.item{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
gap: 12rpx; |
|||
.num{ |
|||
color: #29D3B4; |
|||
font-size: 56rpx; |
|||
} |
|||
.intro{ |
|||
color: #AAAAAA; |
|||
font-size: 24rpx; |
|||
} |
|||
} |
|||
} |
|||
.bottom{ |
|||
font-size: 24rpx; |
|||
color: #333333; |
|||
text{ |
|||
margin-left: 10rpx; |
|||
color: #29D3B4; |
|||
} |
|||
.reduce{ |
|||
color: #ef95a0; |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
.bg_box{ |
|||
z-index: 1; |
|||
width: 100%; |
|||
height: 150rpx; |
|||
} |
|||
|
|||
.bg_top{ |
|||
position: absolute; |
|||
top: 0; |
|||
background-color: #29D3B4; |
|||
} |
|||
.bg_bottom{ |
|||
top: 50%; |
|||
position: absolute; |
|||
background-color: #292929; |
|||
} |
|||
} |
|||
|
|||
.main_section{ |
|||
background: #292929 100%; |
|||
padding: 0 24rpx; |
|||
padding-top: 40rpx; |
|||
padding-bottom: 150rpx; |
|||
font-size: 24rpx; |
|||
color: #333333; |
|||
|
|||
.grid_container { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 40rpx 24rpx; |
|||
display: grid; |
|||
grid-template-columns: repeat(3, 1fr); |
|||
gap: 40rpx 20rpx; |
|||
|
|||
.grid_item { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 20rpx 10rpx; |
|||
border-radius: 12rpx; |
|||
transition: all 0.3s ease; |
|||
|
|||
&:active { |
|||
background-color: #f5f5f5; |
|||
transform: scale(0.95); |
|||
} |
|||
|
|||
.icon_wrapper { |
|||
width: 80rpx; |
|||
height: 80rpx; |
|||
background: rgba(41, 211, 180, 0.1); |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.item_text { |
|||
font-size: 24rpx; |
|||
color: #333333; |
|||
text-align: center; |
|||
font-weight: 400; |
|||
line-height: 1.2; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
</style> |
|||
@ -1,505 +0,0 @@ |
|||
<!--销售-个人资料-详情--> |
|||
<template> |
|||
<view class="main_box"> |
|||
|
|||
<view class="main_section"> |
|||
<view class="section"> |
|||
<view class="item"> |
|||
<image |
|||
@click="changeAvatar()" |
|||
class="pic" |
|||
:src="$util.img(formData.head_img)" |
|||
></image> |
|||
|
|||
<view class="btn" @click="changeAvatar()">修改头像</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="section"> |
|||
<view class="item"> |
|||
<view class="title"> |
|||
姓名 <text class="required">*</text> |
|||
</view> |
|||
<view class="input"> |
|||
<input v-model="formData.name" placeholder="请输入姓名" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="item"> |
|||
<view class="title"> |
|||
账号 <text class="required"></text> |
|||
</view> |
|||
<view class="input"> |
|||
<input v-model="formData.username" disabled placeholder="暂无" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="item"> |
|||
<view class="title"> |
|||
部门 <text class="required"></text> |
|||
</view> |
|||
<view class="input"> |
|||
<!-- <input disabled :placeholder="formData.department_name_str" />--> |
|||
<view class="dept disabled">{{formData.department_name_str || '暂无'}}</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="item"> |
|||
<view class="title"> |
|||
等级 <text class="required"></text> |
|||
</view> |
|||
<view class="input"> |
|||
<input v-model="formData.member_level_name" disabled placeholder="暂无" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="section"> |
|||
<view class="item"> |
|||
<view class="title"> |
|||
性别 <text class="required">*</text> |
|||
</view> |
|||
<view class="input"> |
|||
<input placeholder="请选择性别" v-model="formData.gender_str" @click="picker_show_sex=true"/> |
|||
<fui-picker |
|||
layer="1" |
|||
:linkage="true" |
|||
:options="options_sex_arr" |
|||
:show="picker_show_sex" |
|||
@change="changePickerSex" |
|||
@cancel="picker_show_sex=false" |
|||
></fui-picker> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="item"> |
|||
<view class="title"> |
|||
生日 <text class="required">*</text> |
|||
</view> |
|||
<view class="input"> |
|||
<input placeholder="请选择生日" @click="picker_show_birthday=true" v-model="formData.birthday"/> |
|||
<fui-date-picker |
|||
:minDate="minDate" |
|||
:maxDate="maxDate" |
|||
:show="picker_show_birthday" |
|||
type="3" |
|||
@change="changePickerBirthday" |
|||
@cancel="picker_show_birthday=false" |
|||
></fui-date-picker> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="item"> |
|||
<view class="title"> |
|||
邮箱 <text class="required">*</text> |
|||
</view> |
|||
<view class="input"> |
|||
<input v-model="formData.email" placeholder="请输入邮箱" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="item"> |
|||
<view class="title"> |
|||
手机 <text class="required">*</text> |
|||
</view> |
|||
<view class="input"> |
|||
<input v-model="formData.phone" placeholder="请输入手机" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="item"> |
|||
<view class="title"> |
|||
微信 <text class="required"></text> |
|||
</view> |
|||
<view class="input"> |
|||
<input v-model="formData.wx" placeholder="请输入微信" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="submet_btn" @click="submit">提交</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import apiRoute from '@/api/apiRoute.js'; |
|||
import marketApi from '@/api/market.js'; |
|||
import { |
|||
Api_url |
|||
} from "@/common/config.js"; |
|||
import AQTabber from "@/components/AQ/AQTabber" |
|||
|
|||
|
|||
export default { |
|||
components: { |
|||
AQTabber, |
|||
}, |
|||
data() { |
|||
return { |
|||
formData:{ |
|||
head_img:'',//头像地址 |
|||
name:'',//姓名 |
|||
username:'',//账号 |
|||
address:'',//住址 |
|||
gender:'',//性别|1男,2女 |
|||
gender_str:'', |
|||
birthday:'',//生日 |
|||
email:'',//邮箱 |
|||
phone:'',//手机 |
|||
wx:'',//微信号 |
|||
}, |
|||
|
|||
userInfo: {}, |
|||
|
|||
//上传图片APi路径 |
|||
uploadUrl: `${Api_url}/uploadImage`, |
|||
|
|||
//性别选择器 相关 |
|||
picker_show_sex: false, |
|||
sex_name:'请选择', |
|||
options_sex_arr: [ |
|||
{ |
|||
value: 1, |
|||
text: '男' |
|||
}, |
|||
{ |
|||
value: 2, |
|||
text: '女' |
|||
}, |
|||
], |
|||
|
|||
//生日选择器相关 |
|||
minDate: '', |
|||
maxDate: '', |
|||
picker_show_birthday: false, |
|||
upload_type: 1, |
|||
uploadHeadimg: '', |
|||
editHeadimg: '', |
|||
} |
|||
}, |
|||
onLoad() { |
|||
}, |
|||
onShow() { |
|||
this.init() |
|||
}, |
|||
methods: { |
|||
|
|||
async init(){ |
|||
// this.getBirthday() |
|||
this.setDateYear() |
|||
await this.getUserInfo() |
|||
}, |
|||
|
|||
//设置年份 |
|||
setDateYear() { |
|||
let currentYear = new Date().getFullYear(); |
|||
this.minDate = String(currentYear - 100); |
|||
this.maxDate = String(currentYear + 1); |
|||
}, |
|||
|
|||
//获取用户详情 |
|||
async getUserInfo(){ |
|||
let res = await apiRoute.getPersonnelInfo({}) |
|||
if (res.code != 1){ |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
let gender_str = '' |
|||
if(res.data.gender == 1){ |
|||
gender_str = '男' |
|||
}else if(res.data.gender == 2){ |
|||
gender_str = '女' |
|||
} |
|||
|
|||
//用户表单 |
|||
this.formData = { |
|||
head_img: res.data.head_img,//头像地址 |
|||
name: res.data.name,//姓名 |
|||
username: res.data.phone,//账号 |
|||
address: res.data.address,//住址 |
|||
gender: res.data.gender,//性别|1男,2女 |
|||
gender_str:gender_str, |
|||
birthday: res.data.birthday,//生日 |
|||
email: res.data.email || '',//邮箱 |
|||
phone: res.data.phone,//手机 |
|||
wx: res.data.wx || '',//微信号 |
|||
member_level_name: res.data.member_level_name || '',//等级名称 |
|||
department_name_str:res.data.department_name_str || '暂无',//部门名称 |
|||
} |
|||
}, |
|||
|
|||
// 修改头像按钮 |
|||
changeAvatar() { |
|||
uni.chooseImage({ |
|||
count: 1, |
|||
sizeType: ['compressed'], |
|||
sourceType: ['album', 'camera'], |
|||
success: (res) => { |
|||
const tempFilePath = res.tempFilePaths[0] |
|||
// 这里可以调用上传接口 |
|||
this.uploadFilePromise(tempFilePath) |
|||
} |
|||
}) |
|||
}, |
|||
uploadFilePromise(url) { |
|||
let token = uni.getStorageSync('token') || '' |
|||
let a = uni.uploadFile({ |
|||
url: this.uploadUrl, //仅为示例,非真实的接口地址 |
|||
filePath: url, |
|||
name: 'file', |
|||
header: { |
|||
'token': `${token}`, //请求头设置token |
|||
}, |
|||
success: (e) => { |
|||
let res = JSON.parse(e.data.replace(/\ufeff/g, "") || "{}") |
|||
console.log('上传成功2', res) |
|||
if (res.code == 1) { |
|||
this.upload_type = 2 |
|||
this.formData.head_img = res.data.url |
|||
// this.editHeadimg = res.data.path |
|||
// this.uploadHeadimg = res.data.url |
|||
} else { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
} |
|||
}, |
|||
}); |
|||
}, |
|||
|
|||
//性别选择相关 |
|||
changePickerSex(e) { |
|||
console.log('监听选择', e) |
|||
this.formData.gender = e.value |
|||
this.formData.gender_str = e.text |
|||
this.picker_show_sex = false |
|||
}, |
|||
|
|||
//生日选择相关 |
|||
//获取当前年月日+获取30年前的日期 |
|||
getBirthday() { |
|||
let date = new Date(); |
|||
let year = date.getFullYear(); |
|||
let month = date.getMonth() + 1; |
|||
let day = date.getDate(); |
|||
let year_30 = year - 30; |
|||
let month_30 = month; |
|||
let day_30 = day; |
|||
if (month_30 == 2 && day_30 > 28) { |
|||
month_30 = 3; |
|||
day_30 = 1; |
|||
} |
|||
if (month_30 == 4 && day_30 > 30) { |
|||
month_30 = 5; |
|||
day_30 = 1; |
|||
} |
|||
if (month_30 == 6 && day_30 > 30) { |
|||
month_30 = 7; |
|||
day_30 = 1; |
|||
} |
|||
if (month_30 == 9 && day_30 > 30) { |
|||
month_30 = 10; |
|||
day_30 = 1; |
|||
} |
|||
if (month_30 == 11 && day_30 > 30) { |
|||
month_30 = 12; |
|||
day_30 = 1; |
|||
} |
|||
if (month_30 > 12) { |
|||
month_30 = month_30 - 12; |
|||
year_30 = year_30 + 1; |
|||
} |
|||
let minDate = year_30 + "-" + month_30 + "-" + day_30 |
|||
let maxDate = year + "-" + month + "-" + day |
|||
this.minDate = minDate |
|||
this.maxDate = maxDate |
|||
}, |
|||
|
|||
//监听生日选择 |
|||
changePickerBirthday(e) { |
|||
console.log('监听生日选择', e) |
|||
this.formData.birthday = e.result |
|||
this.picker_show_birthday = false |
|||
}, |
|||
|
|||
//提交信息 |
|||
async submit() { |
|||
let data = {...this.formData} |
|||
|
|||
if(!data.head_img){ |
|||
uni.showToast({ |
|||
title: '请上传头像', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if(!data.name){ |
|||
uni.showToast({ |
|||
title: '请填写', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if(!data.gender){ |
|||
uni.showToast({ |
|||
title: '请选择性别', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if(!data.birthday){ |
|||
uni.showToast({ |
|||
title: '请选择生日', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if(!data.email){ |
|||
uni.showToast({ |
|||
title: '请填写邮箱', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if(!data.phone){ |
|||
uni.showToast({ |
|||
title: '请填写手机', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
|
|||
let res = await apiRoute.editPersonnelInfo(data) |
|||
if(res.code != 1){ |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'success' |
|||
}) |
|||
//延迟1s执行 |
|||
setTimeout(() => { |
|||
this.getUserInfo() |
|||
}, 1000) |
|||
}, |
|||
|
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
|
|||
.main_box{ |
|||
background: #292929 ; |
|||
} |
|||
|
|||
//自定义导航栏 |
|||
.navbar_section{ |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
background: #29d3b4; |
|||
.title{ |
|||
padding: 40rpx 0rpx; |
|||
|
|||
/* 小程序端样式 */ |
|||
// #ifdef MP-WEIXIN |
|||
padding: 80rpx 0rpx; |
|||
// #endif |
|||
|
|||
font-size: 30rpx; |
|||
color: #315d55; |
|||
} |
|||
} |
|||
|
|||
.main_section{ |
|||
min-height: 100vh; |
|||
background: #292929 100%; |
|||
padding: 0 0rpx; |
|||
padding-top: 32rpx; |
|||
padding-bottom: 150rpx; |
|||
font-size: 28rpx; |
|||
color: #fff; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 20rpx; |
|||
|
|||
.section{ |
|||
background-color: #434544; |
|||
.item{ |
|||
padding: 20rpx 40rpx; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
.pic{ |
|||
width: 82rpx; |
|||
height: 82rpx; |
|||
border-radius: 50%; |
|||
} |
|||
.btn{} |
|||
|
|||
.title{ |
|||
min-width: 100rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
font-size: 26rpx; |
|||
color: #D7D7D7; |
|||
.required{ |
|||
margin-left: 10rpx; |
|||
color: red; |
|||
} |
|||
} |
|||
.input{ |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
input{ |
|||
text-align: right; |
|||
} |
|||
.dept{ |
|||
width: 50%; |
|||
} |
|||
.disabled{ |
|||
color: #808080; |
|||
//禁止图标 |
|||
cursor: not-allowed; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.submet_btn{ |
|||
margin: 0 auto; |
|||
margin-top: 40rpx; |
|||
border: 2px solid #25a18b; |
|||
color: #25a18b; |
|||
width: 80%; |
|||
height: 80rpx; |
|||
font-size: 30rpx; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
</style> |
|||
@ -1,292 +0,0 @@ |
|||
<!--我的数据--> |
|||
<template> |
|||
<view class="main_box"> |
|||
<!--自定义导航栏--> |
|||
<view class="navbar_section"> |
|||
<view class="navbar_content"> |
|||
<view class="back_btn" @click="goBack"> |
|||
<fui-icon name="arrowleft" size="32" color="#fff"></fui-icon> |
|||
</view> |
|||
<view class="title">我的数据</view> |
|||
<view class="placeholder"></view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="content_section"> |
|||
<!-- 数据概览卡片 --> |
|||
<view class="overview_cards"> |
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="star" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">总客户数</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="check" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">已签客户</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="wallet" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">销售业绩</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card_item"> |
|||
<view class="card_icon"> |
|||
<fui-icon name="calendar" size="40" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="card_content"> |
|||
<view class="card_title">本月任务</view> |
|||
<view class="card_value">--</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 功能按钮区域 --> |
|||
<view class="function_section"> |
|||
<view class="section_title">数据统计</view> |
|||
<view class="function_grid"> |
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="barchart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">客户统计</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="piechart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">业绩统计</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="linechart" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">趋势分析</view> |
|||
</view> |
|||
|
|||
<view class="function_item"> |
|||
<view class="function_icon"> |
|||
<fui-icon name="list" size="32" color="#29D3B4"></fui-icon> |
|||
</view> |
|||
<view class="function_text">详细报表</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 提示信息 --> |
|||
<view class="tips_section"> |
|||
<view class="tips_title">功能说明</view> |
|||
<view class="tips_content"> |
|||
这里将显示您个人的各项数据统计,包括客户数量、销售业绩、任务完成情况等。 |
|||
具体功能待后续开发实现。 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import fuiIcon from "@/components/firstui/fui-icon/fui-icon.vue" |
|||
|
|||
export default { |
|||
components: { |
|||
fuiIcon, |
|||
}, |
|||
data() { |
|||
return { |
|||
|
|||
} |
|||
}, |
|||
onLoad() { |
|||
|
|||
}, |
|||
methods: { |
|||
// 返回上一页 |
|||
goBack() { |
|||
uni.navigateBack() |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.main_box { |
|||
background: #f5f5f5; |
|||
min-height: 100vh; |
|||
} |
|||
|
|||
// 自定义导航栏 |
|||
.navbar_section { |
|||
background: #29D3B4; |
|||
padding-top: 20rpx; |
|||
|
|||
// 小程序端样式 |
|||
// #ifdef MP-WEIXIN |
|||
padding-top: 90rpx; |
|||
// #endif |
|||
|
|||
.navbar_content { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 20rpx 24rpx 40rpx 24rpx; |
|||
|
|||
.back_btn { |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.title { |
|||
font-size: 32rpx; |
|||
color: #fff; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.placeholder { |
|||
width: 60rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 内容区域 |
|||
.content_section { |
|||
padding: 40rpx 24rpx; |
|||
|
|||
// 概览卡片 |
|||
.overview_cards { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
gap: 24rpx; |
|||
margin-bottom: 40rpx; |
|||
|
|||
.card_item { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 20rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.card_icon { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
background: rgba(41, 211, 180, 0.1); |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.card_content { |
|||
flex: 1; |
|||
|
|||
.card_title { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
margin-bottom: 8rpx; |
|||
} |
|||
|
|||
.card_value { |
|||
font-size: 32rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 功能区域 |
|||
.function_section { |
|||
margin-bottom: 40rpx; |
|||
|
|||
.section_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.function_grid { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
gap: 32rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.function_item { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
padding: 24rpx 16rpx; |
|||
border-radius: 12rpx; |
|||
transition: all 0.3s ease; |
|||
|
|||
&:active { |
|||
background-color: #f5f5f5; |
|||
transform: scale(0.95); |
|||
} |
|||
|
|||
.function_icon { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
background: rgba(41, 211, 180, 0.1); |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.function_text { |
|||
font-size: 24rpx; |
|||
color: #333; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 提示信息 |
|||
.tips_section { |
|||
background: #fff; |
|||
border-radius: 16rpx; |
|||
padding: 32rpx 24rpx; |
|||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); |
|||
|
|||
.tips_title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 600; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.tips_content { |
|||
font-size: 24rpx; |
|||
color: #666; |
|||
line-height: 1.6; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,105 +0,0 @@ |
|||
<!--设置页--> |
|||
<template> |
|||
<view class="assemble"> |
|||
<view style="height: 30rpx;"></view> |
|||
<view class="option" @click="update_pass()">修改密码</view> |
|||
<view class="option" @click="privacy_agreement(1)">用户协议</view> |
|||
<view class="option" @click="privacy_agreement(2)">隐私策略</view> |
|||
<view class="option" @click="clearCache()">清空缓存</view> |
|||
|
|||
<view style="width:90%;margin: 60rpx auto;"> |
|||
<fui-button background="#29d3b4" @click="loginOut()">退出账号</fui-button> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
|
|||
} |
|||
}, |
|||
methods: { |
|||
//退出登陆 |
|||
loginOut(){ |
|||
this.$util.loginOut() |
|||
}, |
|||
|
|||
privacy_agreement(type){ |
|||
uni.navigateTo({ |
|||
url: '/pages-common/privacy_agreement?type='+type |
|||
}) |
|||
}, |
|||
update_pass(){ |
|||
uni.navigateTo({ |
|||
url: '/pages-market/my/update_pass' |
|||
}) |
|||
}, |
|||
|
|||
// 清空缓存 |
|||
clearCache() { |
|||
uni.showModal({ |
|||
title: '清空缓存', |
|||
content: '确定要清空所有字典缓存吗?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
this.performClearCache(); |
|||
} |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
// 执行清空缓存操作 |
|||
performClearCache() { |
|||
try { |
|||
// 获取本地存储的所有键 |
|||
const storageInfo = uni.getStorageInfoSync(); |
|||
const keys = storageInfo.keys; |
|||
|
|||
// 筛选出dict_开头的键并删除 |
|||
let clearCount = 0; |
|||
keys.forEach(key => { |
|||
if (key.startsWith('dict_')) { |
|||
uni.removeStorageSync(key); |
|||
clearCount++; |
|||
} |
|||
}); |
|||
|
|||
// 显示清理结果 |
|||
uni.showToast({ |
|||
title: `已清空${clearCount}个字典缓存`, |
|||
icon: 'success', |
|||
duration: 2000 |
|||
}); |
|||
|
|||
console.log(`清空缓存完成,共清理${clearCount}个dict_开头的缓存项`); |
|||
} catch (error) { |
|||
console.error('清空缓存失败:', error); |
|||
uni.showToast({ |
|||
title: '清空缓存失败', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.assemble{ |
|||
width: 100%; |
|||
height: 100vh; |
|||
background: #333333; |
|||
} |
|||
.option{ |
|||
margin-bottom: 20rpx; |
|||
background: #404045; |
|||
width: 100%; |
|||
font-size: 28rpx; |
|||
color: #fff; |
|||
line-height: 56rpx; |
|||
padding: 20rpx 0 20rpx 100rpx; |
|||
} |
|||
</style> |
|||
@ -1,275 +0,0 @@ |
|||
<!--已签客户-列表--> |
|||
<template> |
|||
<view class="main_box"> |
|||
<!--自定义导航栏--> |
|||
<!-- <view class="navbar_section">--> |
|||
<!-- <view class="title">班级详情</view>--> |
|||
<!-- </view>--> |
|||
|
|||
<view class="main_section"> |
|||
<!-- 班级成员列表--> |
|||
<scroll-view |
|||
class="section_4" |
|||
scroll-y="true" |
|||
:lower-threshold="lowerThreshold" |
|||
@scrolltolower="loadMoreData" |
|||
style="height: 83vh;" |
|||
> |
|||
<view class="ul"> |
|||
<view class="li" |
|||
v-for="(v,k) in tableList" |
|||
:key="k" |
|||
@click="openViewStudentInfo(v)"> |
|||
<view class="left"> |
|||
<view class="box_1"> |
|||
<image class="pic" |
|||
v-if="v.header" :src="$util.img(v.header)"></image> |
|||
<image v-else class="pic" :src="$util.img('/uniapp_src/static/images/index/myk.png')"></image> |
|||
<!-- <view class="tag_box">--> |
|||
<!-- 即将到期--> |
|||
<!-- </view>--> |
|||
</view> |
|||
<view class="box_2"> |
|||
<view class="name">{{v.name}}</view> |
|||
<view class="date">课程截止时间:{{v.end_time}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="right"> |
|||
<view class="item"> |
|||
<view>{{v.have_study_time}}</view> |
|||
<view>已上课时</view> |
|||
</view> |
|||
<view class="item"> |
|||
<view>{{v.end_study_time ? v.end_study_time:0}}</view> |
|||
<view>剩余课时</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
|
|||
<!-- 底部导航--> |
|||
<!-- <AQTabber/>--> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import marketApi from '@/api/market.js'; |
|||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|||
|
|||
|
|||
export default { |
|||
components: { |
|||
AQTabber, |
|||
}, |
|||
data() { |
|||
return { |
|||
loading:false,//加载状态 |
|||
lowerThreshold: 100,//距离底部多远触发 |
|||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|||
|
|||
//筛选条件 |
|||
filteredData:{ |
|||
page:1,//当前页码 |
|||
limit:10,//每页返回数据条数 |
|||
total:10,//数据总条数 |
|||
name: '',//班级名称 |
|||
}, |
|||
tableList:[],//聊天数据列表 |
|||
} |
|||
}, |
|||
onLoad() { |
|||
}, |
|||
onShow() { |
|||
this.init(); |
|||
}, |
|||
methods: { |
|||
//初始化 |
|||
async init(){ |
|||
await this.getList()//获取已签客户 |
|||
}, |
|||
|
|||
//加载更多(下一页) |
|||
loadMoreData() { |
|||
//判断是否加载 |
|||
if (!this.isReachedBottom) { |
|||
this.isReachedBottom = true;//设置为不可请求状态 |
|||
this.getList(); |
|||
} |
|||
}, |
|||
//重置为第一页 |
|||
async resetFilteredData() { |
|||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|||
|
|||
this.filteredData.page = 1//当前页码 |
|||
this.filteredData.limit = 10//每页返回数据条数 |
|||
this.filteredData.total = 10//数据总条数 |
|||
}, |
|||
//获取列表 |
|||
async getList(){ |
|||
this.loading = true |
|||
|
|||
let data = {...this.filteredData} |
|||
|
|||
//判断是否还有数据 |
|||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|||
this.loading = false |
|||
uni.showToast({ |
|||
title: '暂无更多', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if(data.page == 1){ |
|||
this.tableList = [] |
|||
} |
|||
|
|||
let res = await marketApi.signClient(data) |
|||
this.loading = false |
|||
this.isReachedBottom = false; |
|||
if (res.code != 1){ |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
this.tableList = this.tableList.concat(res.data.data); // 使用 concat 方法 将新数据追加到数组中 |
|||
|
|||
console.log('列表',this.tableList) |
|||
this.filteredData.total = res.data.total |
|||
this.filteredData.page++ |
|||
}, |
|||
|
|||
//打开学员详情页 |
|||
openViewStudentInfo(item){ |
|||
let students_id= item.id |
|||
uni.navigateTo({ |
|||
url: `/pages-coach/coach/student/info?students_id=${students_id}` |
|||
}) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
|
|||
.main_box{ |
|||
background: #292929 ; |
|||
} |
|||
|
|||
//自定义导航栏 |
|||
.navbar_section{ |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
background: #292929; |
|||
.title{ |
|||
padding: 40rpx 0rpx; |
|||
|
|||
/* 小程序端样式 */ |
|||
// #ifdef MP-WEIXIN |
|||
padding: 80rpx 0rpx; |
|||
// #endif |
|||
|
|||
font-size: 30rpx; |
|||
color: #fff; |
|||
} |
|||
} |
|||
|
|||
.main_section{ |
|||
min-height: 95vh; |
|||
background: #292929 100%; |
|||
padding: 0 24rpx; |
|||
padding-top: 40rpx; |
|||
padding-bottom: 150rpx; |
|||
font-size: 24rpx; |
|||
color: #FFFFFF; |
|||
//班级成员列表 |
|||
.section_4{ |
|||
.ul{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 10rpx; |
|||
.li{ |
|||
padding: 20rpx 0; |
|||
padding-bottom: 40rpx; |
|||
border-bottom: 2px solid #D7D7D7; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
.left{ |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 30rpx; |
|||
.box_1{ |
|||
padding-left: 20rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
position: relative; |
|||
.pic{ |
|||
width: 84rpx; |
|||
height: 84rpx; |
|||
border-radius: 50%; |
|||
} |
|||
.tag_box{ |
|||
position: absolute; |
|||
bottom: -30rpx; |
|||
width: 120rpx; |
|||
height: 38rpx; |
|||
background-color: #F59A23; |
|||
border-radius: 4rpx; |
|||
line-height: 35rpx; |
|||
text-align: center; |
|||
font-size: 20rpx; |
|||
} |
|||
} |
|||
.box_2{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 20rpx; |
|||
.name{ |
|||
font-size: 28rpx; |
|||
} |
|||
.date{ |
|||
font-size: 24rpx; |
|||
} |
|||
} |
|||
} |
|||
.right{ |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 14rpx; |
|||
.item{ |
|||
border: 1px solid #00E5BB; |
|||
border-radius: 10rpx; |
|||
width: 102rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
view{ |
|||
text-align: center; |
|||
height: 50rpx; |
|||
line-height: 50rpx; |
|||
} |
|||
view:nth-child(1){ |
|||
font-size: 32rpx; |
|||
background-color: #fff; |
|||
color: #00e5bb; |
|||
} |
|||
view:nth-child(2){ |
|||
font-size: 20rpx; |
|||
background-color: #00e5bb; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
</style> |
|||
@ -1,225 +0,0 @@ |
|||
<!--修改密码--> |
|||
<template> |
|||
<view> |
|||
<view class="title"> |
|||
<view :class="{'green-text': tset_style === 1}">1.验证旧密码</view> |
|||
<view :class="{'green-text': tset_style === 2}">2.设置新密码</view> |
|||
</view> |
|||
<view :style="{'background-color':'#fff','width':'100%','height':'100vh' }"> |
|||
<view style="width: 95%;height: 30rpx;"></view> |
|||
<view v-if="tset_style == 1"> |
|||
<view class="describe"> |
|||
为保障您的账号安全,修改密码前请填写原密码 |
|||
</view> |
|||
<view style="width: 95%;margin:30rpx auto;"> |
|||
<fui-input borderTop placeholder="请输入原登录密码" v-model="old_password" |
|||
backgroundColor="#f2f2f2"></fui-input> |
|||
</view> |
|||
</view> |
|||
<view v-if="tset_style == 2"> |
|||
<view style="width: 95%;margin:30rpx auto;"> |
|||
<fui-input borderTop placeholder="请设置6-20位新的登录密码" v-model="formData.new_password" @input="input" |
|||
backgroundColor="#f2f2f2"></fui-input> |
|||
</view> |
|||
<view style="width: 95%;margin: auto;"> |
|||
<fui-input borderTop :padding="['20rpx','32rpx']" v-model="formData.new_password_2" placeholder="请再次输入新的登录密码" @input="input" |
|||
backgroundColor="#f2f2f2"> |
|||
</fui-input> |
|||
</view> |
|||
</view> |
|||
<view style="width: 95%;margin:60rpx auto;"> |
|||
<view class="btn_box"> |
|||
<fui-button |
|||
background="#465cff" |
|||
radius="5rpx" |
|||
@click="nextStep(1)" |
|||
v-if="tset_style != 1">上一步 |
|||
</fui-button> |
|||
|
|||
<fui-button background="#00be8c" radius="5rpx" @click="nextStep(2)" v-if="tset_style == 1">下一步</fui-button> |
|||
|
|||
<fui-button background="#00be8c" radius="5rpx" @click="submit" v-if="tset_style == 2">提交</fui-button> |
|||
</view> |
|||
|
|||
|
|||
<view style="width: 95%;margin:60rpx auto;"> |
|||
<fui-button background="#fff" radius="5rpx" @click="forgot" color="#999999" v-if="tset_style == 1">忘记原密码</fui-button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import apiRoute from '@/api/apiRoute.js'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
code: '', |
|||
user: '', |
|||
tset_style: 1,//tab栏目|1=验证旧密码页,2=设置新密码页 |
|||
|
|||
old_password:'',//旧密码 |
|||
|
|||
|
|||
formData:{ |
|||
phone:'',//当前登录用户的手机号 |
|||
new_password:'',//新密码 |
|||
new_password_2:'',//二次新密码 |
|||
key_value:'',//修改密码的key_value |
|||
}, |
|||
} |
|||
}, |
|||
onLoad() {}, |
|||
onShow() { |
|||
this.init()//初始化 |
|||
}, |
|||
methods: { |
|||
//初始化 |
|||
async init(){ |
|||
await this.getUserInfo() |
|||
}, |
|||
//获取用户信息 |
|||
async getUserInfo() { |
|||
let res = await apiRoute.getPersonnelInfo({}) |
|||
if (res.code != 1) { |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
this.formData.phone = res.data.phone//用户手机号 |
|||
}, |
|||
|
|||
//上/下一步切换 |
|||
async nextStep(tset_style){ |
|||
//tset_style|1=第一页,2=第二页 |
|||
if(tset_style == 2){ |
|||
if(!this.old_password){ |
|||
uni.showToast({ |
|||
title: '请输入原登录密码', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
//验证旧密码 |
|||
let params = { |
|||
old_password: this.old_password |
|||
} |
|||
//验证旧密码是否正确 |
|||
let res = await apiRoute.common_personnelCheckOldPwd(params) |
|||
if(!res.code){ |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
this.formData.key_value = res.data.key_value |
|||
} |
|||
this.tset_style = Number(tset_style) |
|||
}, |
|||
//忘记密码 |
|||
forgot() { |
|||
uni.navigateTo({ |
|||
url: '/pages/student/login/forgot' |
|||
}) |
|||
}, |
|||
|
|||
//提交 |
|||
async submit() { |
|||
//验证数据 |
|||
if (!this.formData.new_password) { |
|||
uni.showToast({ |
|||
title: '请输入新密码', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if (this.formData.new_password.length < 6 || this.formData.new_password.length > 20) { |
|||
uni.showToast({ |
|||
title: '新密码长度为6-20位', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
if (!this.formData.new_password) { |
|||
uni.showToast({ |
|||
title: '请输入新密码', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
//验证两次密码是否一致 |
|||
if (this.formData.new_password != this.formData.new_password_2) { |
|||
uni.showToast({ |
|||
title: '两次密码不一致', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
|
|||
let res = await apiRoute.common_personnelEdidPassword(this.formData) |
|||
if(!res.code){ |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
uni.showToast({ |
|||
title: res.msg, |
|||
icon: 'success' |
|||
}) |
|||
//延迟1s执行 |
|||
setTimeout(() => { |
|||
uni.navigateBack() |
|||
}, 1000) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
page { |
|||
font-weight: normal; |
|||
} |
|||
|
|||
.fui-section__title { |
|||
margin-left: 32rpx; |
|||
} |
|||
|
|||
.fui-left__icon { |
|||
padding-right: 24rpx; |
|||
} |
|||
|
|||
.title { |
|||
display: flex; |
|||
justify-content: space-around; |
|||
align-items: center; |
|||
height: 100rpx; |
|||
width: 100%; |
|||
background-color: #fff; |
|||
font-size: 26rpx; |
|||
border: 4rpx #f5f5f5 solid; |
|||
} |
|||
|
|||
.green-text{ |
|||
color: #36d6b9; |
|||
} |
|||
|
|||
.describe{ |
|||
color: #999999; |
|||
padding-left: 30rpx; |
|||
} |
|||
|
|||
.btn_box{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 40rpx; |
|||
} |
|||
</style> |
|||
@ -1,136 +0,0 @@ |
|||
<template> |
|||
<view class="reim-detail-page"> |
|||
<view class="header-bar"> |
|||
<view class="title">报销详情</view> |
|||
</view> |
|||
<view class="detail-box"> |
|||
<view class="row"> |
|||
<view class="label">报销金额</view> |
|||
<view class="value">¥{{ detail.amount }}</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">报销描述</view> |
|||
<view class="value">{{ detail.description }}</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">发票/收据</view> |
|||
<view class="value"> |
|||
<image v-if="detail.receipt_url && isImage(detail.receipt_url)" :src="detail.receipt_url" class="receipt-img" mode="aspectFit" /> |
|||
<view v-else-if="detail.receipt_url" class="file-link">{{ detail.receipt_url }}</view> |
|||
<text v-else>无附件</text> |
|||
</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">状态</view> |
|||
<view :class="['value', 'status-' + detail.status]">{{ statusMap[detail.status] || detail.status }}</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">创建时间</view> |
|||
<view class="value">{{ detail.created_at }}</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">修改时间</view> |
|||
<view class="value">{{ detail.updated_at }}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
detail: {}, |
|||
statusMap: { |
|||
pending: '待审批', |
|||
approved: '已批准', |
|||
rejected: '已拒绝', |
|||
}, |
|||
} |
|||
}, |
|||
onLoad(options) { |
|||
if (options.id) { |
|||
this.fetchDetail(options.id); |
|||
} else { |
|||
uni.showToast({ title: '缺少报销ID', icon: 'none' }); |
|||
uni.navigateBack(); |
|||
} |
|||
}, |
|||
methods: { |
|||
fetchDetail(id) { |
|||
// 模拟接口获取详情 |
|||
uni.showLoading({ title: '加载中...' }); |
|||
setTimeout(() => { |
|||
const mockData = { |
|||
id: id, |
|||
amount: 300.00, |
|||
description: '办公用品采购(已批准)', |
|||
receipt_url: 'https://cdn.uviewui.com/uview/swiper/1.jpg', |
|||
status: 'approved', |
|||
created_at: '2024-06-02 09:30', |
|||
updated_at: '2024-06-03 12:00', |
|||
}; |
|||
this.detail = mockData; |
|||
uni.hideLoading(); |
|||
}, 500); |
|||
}, |
|||
isImage(url) { |
|||
if (!url) return false; |
|||
return /\.(jpg|jpeg|png|gif|bmp)$/i.test(url) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.reim-detail-page { |
|||
min-height: 100vh; |
|||
background: #292929; |
|||
} |
|||
.header-bar { |
|||
padding: 32rpx 32rpx 0 32rpx; |
|||
.title { |
|||
font-size: 36rpx; |
|||
color: #24BA9F; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
.detail-box { |
|||
margin: 32rpx; |
|||
background: #434544; |
|||
border-radius: 18rpx; |
|||
padding: 32rpx 24rpx 24rpx 24rpx; |
|||
} |
|||
.row { |
|||
display: flex; |
|||
align-items: flex-start; |
|||
margin-bottom: 32rpx; |
|||
.label { |
|||
color: #aaa; |
|||
font-size: 28rpx; |
|||
width: 180rpx; |
|||
flex-shrink: 0; |
|||
margin-top: 10rpx; |
|||
} |
|||
.value { |
|||
color: #fff; |
|||
font-size: 28rpx; |
|||
word-break: break-all; |
|||
} |
|||
.status-pending { color: #f0ad4e; } |
|||
.status-approved { color: #24BA9F; } |
|||
.status-rejected { color: #e74c3c; } |
|||
.receipt-img { |
|||
width: 160rpx; |
|||
height: 160rpx; |
|||
border-radius: 8rpx; |
|||
background: #222; |
|||
border: 1rpx solid #333; |
|||
} |
|||
.file-link { |
|||
color: #24BA9F; |
|||
font-size: 26rpx; |
|||
word-break: break-all; |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,144 +0,0 @@ |
|||
<template> |
|||
<view class="reim-list-page"> |
|||
<view class="header-bar"> |
|||
<view class="title">报销列表</view> |
|||
<fui-button |
|||
background="transparent" |
|||
color="#24BA9F" |
|||
borderColor="#24BA9F" |
|||
width="180rpx" |
|||
height="64rpx" |
|||
radius="32rpx" |
|||
@click="goAdd"> |
|||
新增报销 |
|||
</fui-button> |
|||
</view> |
|||
<view v-if="list.length === 0" class="empty-tip">暂无报销记录</view> |
|||
<view v-for="item in list" :key="item.id" class="reim-card" @click="goDetail(item)"> |
|||
<view class="row"> |
|||
<view class="label">金额:</view> |
|||
<view class="value">¥{{ item.amount }}</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">描述:</view> |
|||
<view class="value">{{ item.description }}</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">发票/收据:</view> |
|||
<view class="value"> |
|||
<image v-if="item.receipt_url" :src="item.receipt_url" class="receipt-img" mode="aspectFit" /> |
|||
<text v-else>无附件</text> |
|||
</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">状态:</view> |
|||
<view :class="['value', 'status-' + item.status]">{{ statusMap[item.status] || item.status }}</view> |
|||
</view> |
|||
<view class="row"> |
|||
<view class="label">创建时间:</view> |
|||
<view class="value">{{ item.created_at }}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import apiRoute from '@/api/apiRoute.js'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
list: [], |
|||
statusMap: { |
|||
pending: '待审批', |
|||
approved: '已批准', |
|||
rejected: '已拒绝', |
|||
}, |
|||
} |
|||
}, |
|||
async onShow() { |
|||
await this.reimbursementList(); |
|||
}, |
|||
methods: { |
|||
async reimbursementList(){ |
|||
let res = await apiRoute.reimbursement_list({}) |
|||
this.list = res.data; |
|||
|
|||
}, |
|||
goAdd() { |
|||
uni.navigateTo({ |
|||
url: '/pages-market/reimbursement/add' |
|||
}); |
|||
}, |
|||
goDetail(item) { |
|||
// 待审批状态可编辑,否则只能查看 |
|||
if (item.status === 'pending') { |
|||
this.$navigateToPage(`/pages-market/reimbursement/add`, { |
|||
id: item.id |
|||
}); |
|||
} else { |
|||
this.$navigateToPage(`/pages-market/reimbursement/detail`, { |
|||
id: item.id |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.reim-list-page { |
|||
min-height: 100vh; |
|||
background: #292929; |
|||
padding-bottom: 120rpx; |
|||
} |
|||
.header-bar { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
padding: 32rpx 32rpx 0 32rpx; |
|||
.title { |
|||
font-size: 36rpx; |
|||
color: #fff; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
.empty-tip { |
|||
color: #888; |
|||
text-align: center; |
|||
margin: 80rpx 0; |
|||
} |
|||
.reim-card { |
|||
background: #434544; |
|||
border-radius: 18rpx; |
|||
margin: 32rpx; |
|||
margin-bottom: 0; |
|||
padding: 32rpx 24rpx 24rpx 24rpx; |
|||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.08); |
|||
.row { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 18rpx; |
|||
.label { |
|||
color: #aaa; |
|||
font-size: 26rpx; |
|||
width: 140rpx; |
|||
flex-shrink: 0; |
|||
} |
|||
.value { |
|||
color: #fff; |
|||
font-size: 28rpx; |
|||
word-break: break-all; |
|||
} |
|||
.status-pending { color: #f0ad4e; } |
|||
.status-approved { color: #24BA9F; } |
|||
.status-rejected { color: #e74c3c; } |
|||
.receipt-img { |
|||
width: 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 8rpx; |
|||
background: #222; |
|||
border: 1rpx solid #333; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue