This commit is contained in:
wuzhimiao
2025-10-31 09:30:04 +08:00
parent 577b20661a
commit e84b367360
151 changed files with 10747 additions and 17 deletions

View File

@@ -0,0 +1,665 @@
<template>
<view class="page">
<u-navbar
title="帮扶登记"
:autoBack="true"
bgColor="transparent"
leftIconColor="#fff"
:titleStyle="{ color: '#fff' }"
></u-navbar>
<view class="input-outer-part">
<scroll-view scroll-y="true" style="height: calc(100vh - 100px)">
<view class="inner">
<div class="self-form">
<view class="inner-part">
<div class="form-item required">
<label class="form-label">被帮扶对象</label>
<input
v-model="serviceForm.serviceObjectName"
style="border: none; width: 100%; padding: 10px 0;"
placeholder="请输入"
disabled
/>
</div>
<div class="form-item required">
<label class="form-label">帮扶方式</label>
<div class="form-value" @click="showPicker('demandType')" :class="{ noValue: !serviceForm.demandType }">
{{ getDemandTypeLabel(serviceForm.demandType) || "请选择" }}
<span class="arrow-down"></span>
</div>
</div>
<div class="form-item required" v-if="serviceForm.demandType == '4' || serviceForm.demandType == '5'">
<label class="form-label">帮扶时间</label>
<div class="form-value" @click="showPicker('practicalSolutionTime')" :class="{ noValue: !serviceForm.practicalSolutionTime }">
{{ serviceForm.practicalSolutionTime || "请选择" }}
<span class="arrow-down"></span>
</div>
</div>
<div class="form-item required" v-if="serviceForm.demandType == '4' || serviceForm.demandType == '5'">
<label class="form-label">经办人</label>
<div class="form-select-wrapper">
<el-select
style="width: 100%"
v-model="serviceForm.agentUserId"
placeholder="请选择经办人"
@change="handleAgentChange"
>
<el-option
v-for="item in jingbrList1"
:key="item.userId"
:label="item.nickName"
:value="item.userId"
></el-option>
</el-select>
</div>
</div>
<div class="form-item required" v-if="serviceForm.demandType == '5'">
<label class="form-label">电话沟通结果</label>
<div class="form-value" @click="showPicker('dhgtjg')" :class="{ noValue: !serviceForm.dhgtjg }">
{{ getDhgtjgLabel(serviceForm.dhgtjg) || "请选择" }}
<span class="arrow-down"></span>
</div>
</div>
<div class="form-item required" v-if="serviceForm.demandType == '4' || serviceForm.demandType == '5'">
<label class="form-label">帮扶内容</label>
<div class="form-value" @click="showPicker('serviceContent')" :class="{ noValue: !serviceForm.serviceContent }">
{{ getServiceContentLabel(serviceForm.serviceContent) || "请选择" }}
<span class="arrow-down"></span>
</div>
</div>
</view>
<view class="inner-part">
<div class="form-item required" v-if="serviceForm.demandType == '4' || serviceForm.demandType == '5'">
<label class="form-label">帮扶情况说明</label>
<textarea
v-model="serviceForm.blqksm"
style="width: 100%; border: none; padding: 10px 0; min-height: 100px; resize: none;"
placeholder="请输入"
></textarea>
</div>
<div class="form-item required" v-if="serviceForm.demandType == '4' || serviceForm.demandType == '5'">
<label class="form-label">人员状态</label>
<div class="radio-group">
<label class="radio-item" v-for="item in personStatusOptions" :key="item.value">
<input type="radio" name="personStatus" :value="item.value" v-model="serviceForm.personStatus" />
<span class="radio-label">{{ item.label }}</span>
</label>
</div>
</div>
</view>
<view class="inner-part" v-if="serviceForm.demandType == '4' || serviceForm.demandType == '5'">
<div class="form-item">
<label class="form-label">附件</label>
<div style="width: 100%; padding: 10px 0;">
<button @click="triggerFileUpload" style="padding: 8px 16px; background: #f0f0f0; border: none; border-radius: 4px;">
上传附件 (最多6个)
</button>
<!-- 简单的文件列表显示 -->
<div v-if="serviceForm.fileUrl.length > 0" class="file-list">
<div v-for="(file, index) in serviceForm.fileUrl" :key="index" class="file-item">
{{ file.name }}
<span @click="removeFile(index)" style="margin-left: 10px; cursor: pointer; color: #ff4444;">删除</span>
</div>
</div>
</div>
</div>
</view>
</div>
</view>
</scroll-view>
<view class="button-area">
<view class="btn" @click="cancelPage">取消</view>
<view class="btn save" @click="submitServiceForm">保存</view>
</view>
</view>
<!-- 通用选择器 -->
<div v-if="currentPicker" class="datetime-picker-overlay">
<div class="datetime-picker">
<div class="picker-header">
<span @click="cancelPicker" style="padding: 10px;">取消</span>
<span style="font-weight: bold;">{{ getPickerTitle(currentPicker) }}</span>
<span @click="confirmPicker" style="padding: 10px; color: #007AFF;">确定</span>
</div>
<div class="picker-content">
<div v-if="currentPicker === 'practicalSolutionTime'">
<input
type="datetime-local"
v-model="manualDateTime"
style="width: 100%; padding: 15px; box-sizing: border-box;"
/>
</div>
<div v-else class="picker-options">
<div
v-for="option in getPickerOptions(currentPicker)"
:key="option.value"
@click="selectPickerOption(option.value)"
:class="{ 'selected': selectedOption === option.value }"
>
{{ option.label }}
</div>
</div>
</div>
</div>
</div>
</view>
</template>
<script>
import {getJbrInfo} from "../../api/personinfo/index"
export default {
data() {
return {
serviceForm: {
serviceObjectName: '',
userId: '',
demandType: '', // 帮扶方式
practicalSolutionTime: '', // 帮扶时间
agentUserId: '', // 经办人ID
agentUserName: '', // 经办人名称
dhgtjg: '', // 电话沟通结果
serviceContent: '', // 帮扶内容
blqksm: '', // 帮扶情况说明
personStatus: '', // 人员状态
fileUrl: [] // 附件
},
jingbrList1:[],
currentPicker: null,
selectedOption: '',
manualDateTime: this.formatDateTime(new Date()),
// 帮扶方式选项 (4: 上门服务, 5: 电话回访)
demandTypeOptions: [
{ value: '4', label: '上门服务' },
{ value: '5', label: '电话回访' }
],
// 经办人选项(模拟数据)
jingbrList: [
{ userId: '1', nickName: '张三' },
{ userId: '2', nickName: '李四' },
{ userId: '3', nickName: '王五' }
],
// 电话沟通结果选项
dhgtjgOptions: [
{ value: '1', label: '已沟通' },
{ value: '2', label: '未接通' },
{ value: '3', label: '拒绝沟通' }
],
// 帮扶内容选项
serviceContentOptions: [
{ value: '1', label: '政策宣传' },
{ value: '2', label: '就业指导' },
{ value: '3', label: '技能培训' },
{ value: '4', label: '岗位推荐' },
{ value: '5', label: '其他' }
],
// 人员状态选项
personStatusOptions: [
{ value: '1', label: '已就业' },
{ value: '2', label: '未就业' },
{ value: '3', label: '灵活就业' }
]
};
},
async created(){
this.getJbrInfo11()
const serviceContentOptions = await this.$getDictSelectOption('qcjy_fwnr');
console.log('帮扶内容选项:', serviceContentOptions);
this.serviceContentOptions = serviceContentOptions;
const serviceContentOptions1 = await this.$getDictSelectOption('qcjy_ryzt');
this.personStatusOptions=serviceContentOptions1
},
onLoad(options) {
if (options.name) {
this.serviceForm.serviceObjectName = options.name;
}
if (options.id) {
this.serviceForm.userId = options.id;
}
},
methods: {
async getJbrInfo11(){
const res=await getJbrInfo()
this.jingbrList1=res
},
// 显示选择器
showPicker(type) {
this.currentPicker = type;
if (type !== 'practicalSolutionTime') {
this.selectedOption = this.serviceForm[type] || '';
}
},
// 取消选择器
cancelPicker() {
this.currentPicker = null;
},
// 确认选择器
confirmPicker() {
if (this.currentPicker === 'practicalSolutionTime') {
this.manualConfirmDate();
} else {
this.serviceForm[this.currentPicker] = this.selectedOption;
// 特殊处理经办人,同时保存名称
if (this.currentPicker === 'agentUserId') {
const agent = this.jingbrList1.find(item => item.userId === this.selectedOption);
this.serviceForm.agentUserName = agent ? agent.nickName : '';
}
}
this.currentPicker = null;
},
// 选择选项
selectPickerOption(value) {
this.selectedOption = value;
},
// 获取选择器标题
getPickerTitle(type) {
const titles = {
demandType: '选择帮扶方式',
practicalSolutionTime: '选择帮扶时间',
agentUserId: '选择经办人',
dhgtjg: '选择电话沟通结果',
serviceContent: '选择帮扶内容'
};
return titles[type] || '请选择';
},
// 获取选择器选项
getPickerOptions(type) {
const options = {
demandType: this.demandTypeOptions || [],
agentUserId: this.jingbrList1 && this.jingbrList1.length > 0 ?
this.jingbrList1.map(item => ({ value: item.userId, label: item.nickName })) : [],
dhgtjg: this.dhgtjgOptions || [],
serviceContent: this.serviceContentOptions || []
};
return options[type] || [];
},
// 获取帮扶方式标签
getDemandTypeLabel(value) {
const option = this.demandTypeOptions.find(item => item.value === value);
return option ? option.label : '';
},
// 获取经办人名称
getAgentUserName(userId) {
const agent = this.jingbrList1.find(item => item.userId === userId);
return agent ? agent.nickName : '';
},
// 处理经办人选择变化
handleAgentChange(value) {
if (!value || !this.jingbrList1 || !this.jingbrList1.length) {
this.serviceForm.agentUserName = '';
return;
}
const user = this.jingbrList1.find(item => item.userId === value);
if (user) {
this.serviceForm.agentUserName = user.nickName;
} else {
this.serviceForm.agentUserName = '';
}
},
// 获取电话沟通结果标签
getDhgtjgLabel(value) {
const option = this.dhgtjgOptions.find(item => item.value === value);
return option ? option.label : '';
},
// 获取帮扶内容标签
getServiceContentLabel(value) {
const option = this.serviceContentOptions.find(item => item.value === value);
return option ? option.label : '';
},
// 格式化日期时间为YYYY-MM-DDTHH:MM格式datetime-local输入框需要
formatDateTime(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day}T${hours}:${minutes}`;
},
// 手动确认日期选择
manualConfirmDate() {
// 将datetime-local格式转换为显示格式
const date = new Date(this.manualDateTime);
this.serviceForm.practicalSolutionTime = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
},
// 触发文件上传
triggerFileUpload() {
if (this.serviceForm.fileUrl.length < 6) {
// 模拟添加文件
const mockFiles = ['文档.pdf', '图片.jpg', '表格.xlsx', '报告.docx'];
const randomFile = mockFiles[Math.floor(Math.random() * mockFiles.length)];
this.serviceForm.fileUrl.push({
name: randomFile,
url: `mock-url/${Date.now()}/${randomFile}`
});
} else {
uni.showToast({ title: '最多只能上传6个文件', icon: 'none' });
}
},
// 删除文件
removeFile(index) {
this.serviceForm.fileUrl.splice(index, 1);
},
// 取消页面
cancelPage() {
uni.navigateBack();
},
// 验证表单
validateForm() {
if (!this.serviceForm.serviceObjectName) {
uni.showToast({ title: '请填写被帮扶对象', icon: 'none' });
return false;
}
if (!this.serviceForm.demandType) {
uni.showToast({ title: '请选择帮扶方式', icon: 'none' });
return false;
}
// 如果是上门服务或电话回访,需要验证更多字段
if (this.serviceForm.demandType === '4' || this.serviceForm.demandType === '5') {
if (!this.serviceForm.practicalSolutionTime) {
uni.showToast({ title: '请选择帮扶时间', icon: 'none' });
return false;
}
if (!this.serviceForm.agentUserId) {
uni.showToast({ title: '请选择经办人', icon: 'none' });
return false;
}
if (this.serviceForm.demandType === '5' && !this.serviceForm.dhgtjg) {
uni.showToast({ title: '请选择电话沟通结果', icon: 'none' });
return false;
}
if (!this.serviceForm.serviceContent) {
uni.showToast({ title: '请选择帮扶内容', icon: 'none' });
return false;
}
if (!this.serviceForm.blqksm) {
uni.showToast({ title: '请填写帮扶情况说明', icon: 'none' });
return false;
}
if (!this.serviceForm.personStatus) {
uni.showToast({ title: '请选择人员状态', icon: 'none' });
return false;
}
}
return true;
},
// 提交表单
async submitServiceForm() {
try {
// 验证表单
if (!this.validateForm()) {
return;
}
// 模拟加载状态
uni.showLoading({ title: '保存中...' });
// 准备提交数据
const submitData = {
...this.serviceForm,
// 格式化文件数据
fileUrl: JSON.stringify(this.serviceForm.fileUrl)
};
// 打印提交数据
console.log('提交数据:', submitData);
// 模拟API调用延迟
await new Promise(resolve => setTimeout(resolve, 1000));
uni.showToast({ title: '保存成功', icon: 'success' });
uni.navigateBack();
} catch (error) {
console.error(error);
uni.showToast({ title: '保存失败', icon: 'none' });
} finally {
uni.hideLoading();
}
}
}
};
</script>
<style lang="scss" scoped>
.page {
height: 100vh;
background-color: #eef1f5 !important;
background-image: url("~@/static/images/top.png");
background-repeat: no-repeat;
background-size: 100% auto;
}
.input-outer-part {
background: #eef1f5;
padding: 32rpx;
padding-top: 100rpx; /* 增加顶部内边距,防止内容被遮挡 */
position: relative;
top: -80rpx;
border-radius: 32rpx 32rpx 0 0;
}
.inner {
.inner-part {
background: #fff;
padding: 0 32rpx;
border-radius: 16rpx;
margin-bottom: 20rpx;
}
}
.self-form {
// 表单样式
}
/* 表单项目样式 */
.form-item {
display: flex;
align-items: flex-start;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #f0f0f0;
}
/* 选择器容器样式 */
.form-select-wrapper {
flex: 1;
padding: 5px 0;
}
.form-item.required .form-label::after {
content: '*';
color: #ff4444;
margin-left: 4px;
}
.form-label {
width: 110px;
flex-shrink: 0;
font-size: 14px;
color: #333;
padding: 10px 0;
}
.form-value {
flex: 1;
padding: 10px 0;
font-size: 14px;
color: #666;
display: flex;
justify-content: space-between;
align-items: center;
}
.form-value.noValue {
color: #999;
}
.arrow-down {
font-size: 12px;
color: #A6A6A6;
}
.edit-icon {
font-size: 14px;
color: #A6A6A6;
}
.form-input-wrapper {
flex: 1;
position: relative;
}
.form-input-wrapper input {
width: 100%;
padding: 10px 0;
border: none;
outline: none;
font-size: 14px;
}
.form-input-wrapper .edit-icon {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
}
/* 单选按钮样式 */
.radio-group {
flex: 1;
display: flex;
flex-wrap: wrap;
padding: 10px 0;
}
.radio-item {
display: flex;
align-items: center;
margin-right: 20px;
margin-bottom: 10px;
cursor: pointer;
}
.radio-item input[type="radio"] {
margin-right: 6px;
}
.radio-label {
font-size: 14px;
color: #666;
}
/* 文件列表样式 */
.file-list {
margin-top: 10px;
}
.file-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
font-size: 14px;
color: #666;
}
/* 选择器样式 */
.datetime-picker-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
}
.datetime-picker {
background-color: #fff;
border-radius: 8px;
width: 80%;
max-width: 400px;
overflow: hidden;
}
.picker-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
border-bottom: 1px solid #f0f0f0;
font-size: 16px;
}
.picker-content {
max-height: 300px;
overflow-y: auto;
}
.picker-options {
padding: 10px 0;
}
.picker-options > div {
padding: 15px 20px;
font-size: 14px;
color: #666;
}
.picker-options > div.selected {
background-color: #f0f8ff;
color: #1d64cf;
}
.noValue {
color: #c0c4cc;
}
.button-area {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 24rpx 32rpx;
background: #fff;
display: flex;
box-sizing: border-box;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
.btn {
line-height: 72rpx;
width: 176rpx;
margin-right: 16rpx;
font-size: 28rpx;
border: 1px solid #b8c5d4;
color: #282828;
text-align: center;
border-radius: 8rpx;
}
.save {
background: linear-gradient(103deg, #1d64cf 0%, #1590d4 99%);
color: #fff;
border: 0;
flex-grow: 1;
}
}
</style>

View File

@@ -47,9 +47,9 @@
</view>
<view class="titles">
<view class="title-item active"><view>待办需求预警列表</view></view>
<view> 2 条信息</view>
<view> {{jobList1count}}条信息</view>
</view>
<view v-for="(item, index) in jobList" :key="index" class="job-list">
<view v-for="(item, index) in jobList1" :key="index" class="job-list">
<view class="title">销售顾问</view>
<view class="info">
待办内容文字示例待办内容文字示例待办内容文字示例待办内容文字示例
@@ -61,7 +61,7 @@
</view>
<view class="titles">
<view class="title-item active"><view>待服务毕业生列表</view></view>
<view> 22 条信息</view>
<view> {{jobListcount}} 条信息</view>
</view>
<view v-for="(item, index) in jobList" :key="index" class="person-list">
<view class="top-info">
@@ -69,7 +69,7 @@
<image v-else src="../../../packageRc/static/personIconFe.png"/>
<view class="top-right">
<view class="name-line">
<view class="name">姓名<view class="tag">硕士</view></view>
<view class="name">姓名<view class="tag">{{item.name}}</view></view>
<view class="service-status">·未服务</view>
</view>
<view class="info-line" style="display: flex;">
@@ -80,26 +80,139 @@
</view>
<view class="info-line">
<view><text>联系电话</text>152****5488</view>
<view><text>详细地址</text>山东省济南市历城区港沟街道融创文旅城鹊桥华居8号楼1单元801</view>
<view><text>详细地址</text>{{item.xxdz}}</view>
</view>
<view class="services">
<view>退回</view>
<view>服务</view>
<view @click="showReturnReasonPopup">退回</view>
<view @click="tiao(item.id)">服务</view>
</view>
</view>
</view>
</scroll-view>
<!-- 退回原因弹窗 -->
<uni-popup ref="returnReasonPopup" position="center" round>
<view class="popup-content" style="background:rgb(248, 248, 248);">
<textarea
v-model="returnReason"
class="reason-textarea"
placeholder="请输入退回原因"
placeholder-class="placeholder-style"
rows="5"
maxlength="200"
></textarea>
<view class="popup-footer">
<button class="cancel-btn" @click="cancelReturn">取消</button>
<button class="confirm-btn" @click="confirmReturn">确认退回</button>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { personInfoList,personAlertList } from '../../api/personinfo/index'
import { reactive, inject, watch, ref, onMounted, watchEffect, nextTick } from 'vue';
let activeTab = ref(1)
let activeTitle = ref(1)
let jobList = ref([{},{},{},{},{}])
let jobListcount = ref()
let jobList1 = ref([{},{}])
let jobList1count = ref()
// 退回原因弹窗相关
let returnReasonPopup = ref(null)
let returnReason = ref('')
let currentItemIndex = ref(-1)
function back() {
uni.navigateBack({
delta: 1
});
};
onMounted(() => {
getlist();
getlistyujing();
});
async function getlist(){
try {
const res = await personInfoList();
console.log("res", res);
jobList.value = res.rows || [];
jobListcount.value=res.total || 0
} catch (error) {
console.error("获取数据失败:", error);
jobList.value = [];
}
};
async function getlistyujing(){
try {
const res = await personAlertList();
console.log("res", res);
jobList1.value = res.rows || [];
jobList1count.value=res.total || 0
} catch (error) {
console.error("获取数据失败:", error);
jobList1.value = [];
}
};
// 显示退回原因弹窗
function showReturnReasonPopup() {
console.log("退回")
returnReason.value = ''
// 使用 ref 控制弹窗显示
if (returnReasonPopup.value) {
returnReasonPopup.value.open()
}
}
function tiao(id){
console.log('尝试导航到待办详情页面ID:', id);
// 尝试直接使用uni.navigateTo使用正确的格式并传递id参数
uni.navigateTo({
url: `/packageRc/pages/daiban/daibandetail?id=${id}`,
success: function() {
console.log('导航成功');
},
fail: function(err) {
console.error('导航失败:', err);
}
});
}
// 确认退回
function confirmReturn() {
if (!returnReason.value.trim()) {
uni.showToast({
title: '请填写退回原因',
icon: 'none'
})
return
}
// 这里可以添加提交退回原因的API调用
console.log('退回原因:', returnReason.value, '项目索引:', currentItemIndex.value)
// 模拟提交成功
uni.showToast({
title: '退回成功'
})
// 使用 ref 控制弹窗关闭
if (returnReasonPopup.value) {
returnReasonPopup.value.close()
}
}
// 取消退回
function cancelReturn() {
// 使用 ref 控制弹窗关闭
if (returnReasonPopup.value) {
returnReasonPopup.value.close()
}
}
function viewMore() {
// uni.navigateTo({
@@ -139,6 +252,7 @@ view{box-sizing: border-box;display: block;}
margin-top: 16rpx;
font-weight: normal;
}
// text{
// font-size: 28rpx;
// }
@@ -148,6 +262,75 @@ view{box-sizing: border-box;display: block;}
// margin-bottom: 15rpx;
height: 78rpx;
}
/* 退回原因弹窗样式 */
.popup-content {
background: #FFFF;
border-radius: 24rpx;
padding: 48rpx;
width: 88%;
box-sizing: border-box;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.15);
}
.popup-title {
font-size: 36rpx;
font-weight: bold;
color: #282828;
margin-bottom: 36rpx;
text-align: center;
}
.reason-textarea {
width: 100%;
border: 2rpx solid #D8D8D8;
border-radius: 12rpx;
padding: 24rpx;
min-height: 220rpx;
font-size: 30rpx;
color: #333333;
box-sizing: border-box;
background: #FAFAFA;
}
.placeholder-style {
color: #999999;
}
.popup-footer {
display: flex;
justify-content: space-between;
margin-top: 40rpx;
}
.cancel-btn,
.confirm-btn {
flex: 1;
height: 90rpx;
line-height: 90rpx;
border-radius: 16rpx;
font-size: 32rpx;
text-align: center;
margin: 0 15rpx;
font-weight: 500;
}
.cancel-btn {
background: #F8F8F8;
color: #666666;
border: none;
}
.confirm-btn {
background: #1A62CE;
color: #FFFFFF;
border: none;
}
/* 弹窗背景遮罩层样式 */
::v-deep(.uni-popup__wrapper) {
background-color: rgba(0, 0, 0, 0.5);
}
}
.trace-line{
width: 100%;

File diff suppressed because it is too large Load Diff