培训意愿

This commit is contained in:
2026-03-09 17:26:12 +08:00
parent f107001347
commit cd621f659c
7 changed files with 1307 additions and 205 deletions

View File

@@ -103,13 +103,19 @@
<view class="float-btn" @click="goDetail('add')">
<uni-icons type="plusempty" color="#fff" size="30"></uni-icons>
</view>
<view>
<!-- 提示窗示例 -->
<uni-popup ref="alertDialog" type="dialog">
<uni-popup-dialog type="warn" cancelText="取消" confirmText="确定" title="提示" content="确定要删除这条求职意愿吗?" @confirm="dialogConfirm"></uni-popup-dialog>
</uni-popup>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { inject, ref, reactive, onMounted } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { onLoad,onShow } from '@dcloudio/uni-app';
const { $api, navTo, navBack } = inject('globalFunction');
import config from "@/config.js"
@@ -130,6 +136,8 @@ const getBackgroundStyle = (imageName) => ({
backgroundPosition: 'center', // 居中
backgroundRepeat: 'no-repeat'
});
const alertDialog = ref(null);
const currentItem=ref({})
function getDictionary(){
$api.myRequest('/system/public/dict/data/type/education').then((resData) => {
if(resData && resData.code == 200){
@@ -197,19 +205,45 @@ function scrollBottom(){
function goDetail(val,item){
if(val=='add'){
navTo('/packageB/priority/jobWillEdit?goalPersonId=' + goalPersonId.value);
}else{
navTo('/packageB/priority/jobWillEdit?item=' + JSON.stringify(item));
}
}
function del(item){}
function del(item){
if (alertDialog.value) {
alertDialog.value.open();
currentItem.value=item
}
}
function dialogConfirm(){
let header={
'Authorization':uni.getStorageSync('Padmin-Token'),
'Content-Type': "application/x-www-form-urlencoded"
}
$api.myRequest('/dispatch/job/willingness/'+currentItem.value.id,{},'delete',9100,header).then((resData) => {
console.log("resData",resData)
if(resData.code==200){
dataList.value=[]
pageNum.value=1
getDataList()
}
});
}
onLoad((options) => {
id.value=options.id
goalPersonId.value=options.goalPersonId
runAsyncTasks()
});
const runAsyncTasks = async () => {
await getDictionary()
await getDataList()
}
onShow(()=>{
dataList.value=[]
pageNum.value=1
runAsyncTasks()
})
</script>

View File

@@ -3,36 +3,36 @@
<view class="main-list" :style="getBackgroundStyle('k.png')">
<view class="list-top">
<view class="list-title">
<text>新增求职意愿</text>
<text>{{showTitle}}求职意愿</text>
<view class="title-line"></view>
</view>
</view>
<view class="form-container">
<uni-forms ref="formRef" v-model="formData" :rules="rules" validate-trigger="submit" >
<uni-forms-item label="意向岗位:" name="content" required>
<uni-forms-item label="意向岗位:" name="postType" required>
<uni-easyinput v-model="formData.postType" placeholder="请输入意向岗位"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="期望薪资:" name="content" required>
<uni-forms-item label="期望薪资:" name="salary" required>
<uni-easyinput v-model="formData.salary" placeholder="请输入期望薪资"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="意向工作区域:" name="content" required>
<uni-forms-item label="意向工作区域:" name="regionName" required>
<uni-easyinput v-model="formData.regionName" placeholder="请输入意向工作区域"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="期望福利:" name="content" required>
<uni-forms-item label="期望福利:" name="welfare" required>
<uni-easyinput v-model="formData.welfare" placeholder="请输入期望福利"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="学历:" name="followWay" required >
<uni-data-select v-model="formData.followWay" placeholder="请选择学历" :localdata="followWays" @change="onMethodChange"></uni-data-select>
<uni-forms-item label="学历:" name="education" >
<uni-data-select v-model="formData.education" placeholder="请选择学历" :localdata="educationOptions" @change="onEducationChange"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="岗位类型:" name="followWay" required >
<uni-data-select v-model="formData.followWay" placeholder="请选择岗位类型" :localdata="followWays" @change="onMethodChange"></uni-data-select>
<uni-forms-item label="岗位类型:" name="jobType" >
<uni-data-select v-model="formData.jobType" placeholder="请选择岗位类型" :localdata="jobTypeOptions" @change="onJobTypeChange"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="类型:" name="followWay" required >
<uni-data-select v-model="formData.followWay" placeholder="请选择类型" :localdata="followWays" @change="onMethodChange"></uni-data-select>
<uni-forms-item label="类型:" name="type" >
<uni-data-select v-model="formData.type" placeholder="请选择类型" :localdata="typeOptions" @change="onTypeChange"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="意向自述:" name="content" required>
<uni-easyinput type="textarea" v-model="formData.content" placeholder="请输入意向自述"></uni-easyinput>
<uni-forms-item label="意向自述:" name="description" >
<uni-easyinput type="textarea" v-model="formData.description" placeholder="请输入意向自述"></uni-easyinput>
</uni-forms-item>
</uni-forms>
<!-- 按钮组 -->
@@ -52,6 +52,7 @@ const { $api, navTo, navBack } = inject('globalFunction');
import config from "@/config.js"
const title = ref('');
const showTitle=ref('')
const formData = reactive({
id: null,
goalPersonId: '',
@@ -65,6 +66,9 @@ const formData = reactive({
jobType: '',
type: '',
})
const educationOptions=ref([])
const jobTypeOptions=ref([])
const typeOptions=ref([])
const personInfo=ref({
goalPersonId:'',
name:'',
@@ -73,36 +77,33 @@ const personInfo=ref({
person_id:''
})
const followWays = ref([])
const followList = ref([])
const followListNum=ref(0)
const active=ref(null)
// 表单引用
const formRef = ref(null)
// 校验规则
const rules = {
followDate: {
postType: {
rules: [{
required: true,
errorMessage: '请选择跟进日期'
errorMessage: '请输入意向岗位'
}]
},
followWay: {
salary: {
rules: [{
required: true,
errorMessage: '请选择跟进方式'
errorMessage: '请输入期望薪资'
}]
},
content: {
regionName: {
rules: [{
required: true,
errorMessage: '请填写跟进内容'
errorMessage: '请输入意向工作区域'
}]
},
result: {
welfare: {
rules: [{
required: true,
errorMessage: '请填写跟进结果'
errorMessage: '请输入期望福利'
}]
}
}
@@ -114,62 +115,50 @@ const getBackgroundStyle = (imageName) => ({
backgroundRepeat: 'no-repeat'
});
const onFollowDateChange = (e)=>{
formData.followDate=e
const getDictionary = async () => {
try {
const [eduRes, jobRes, gangweiRes] = await Promise.all([
$api.myRequest('/system/public/dict/data/type/education'),
$api.myRequest('/system/public/dict/data/type/job_type'),
$api.myRequest('/system/public/dict/data/type/gangwei_type')
]);
if (eduRes && eduRes.code == 200) {
eduRes.data.forEach(item => {
educationOptions.value.push({
value: item.dictValue,
text: item.dictLabel
});
});
}
if (jobRes && jobRes.code == 200) {
jobRes.data.forEach(item => {
jobTypeOptions.value.push({
value: item.dictValue,
text: item.dictLabel
});
});
}
if (gangweiRes && gangweiRes.code == 200) {
gangweiRes.data.forEach(item => {
typeOptions.value.push({
value: item.dictValue,
text: item.dictLabel
});
});
}
} catch (error) {
console.error("获取字典数据失败:", error);
throw error; // 抛出错误,让外部调用者知道失败了
}
};
function onEducationChange(e){
formData.education=e
}
const onMethodChange = (e) => {
formData.followWay=e
function onJobTypeChange(e){
formData.jobType=e
}
// 事件处理
const onDateChange = ( e) => {
formData.nextContactDate=e
}
function getFollowList(){
followList.value=[]
let header={
'Authorization':uni.getStorageSync('Padmin-Token'),
'Content-Type': "application/x-www-form-urlencoded"
}
let params={
personId:personInfo.value.person_id,
taskId:personInfo.value.task_id
}
$api.myRequest('/dispatch/assist/records/getFollowList', params,'get',9100,header).then((resData) => {
if(resData && resData.code == 200){
if(resData.data && resData.data.length>0){
followListNum.value=resData.data.length
resData.data.forEach(item=>{
const obj={
title:item.followDate,
desc:`跟进方式:${getFollowWaysLabelByValue(item.followWay)}\n跟进人${item.createByName}\n跟进内容${item.content}\n跟进结果${item.result}\n下一步计划${item.nextPlan}`
}
followList.value.push(obj)
})
}
}
});
}
function getDictionary(){
$api.myRequest('/system/public/dict/data/type/assist_follow_way').then((resData) => {
if(resData && resData.code == 200){
resData.data.forEach(item=>{
const obj = {
value: item.dictValue,
text: item.dictLabel
}
followWays.value.push(obj)
})
}
});
}
function getFollowWaysLabelByValue(value) {
if (!Array.isArray(followWays.value)) {
return ''
}
const item = followWays.value.find(item => item.value === String(value))
return item ? item.text : '暂无跟进方式'
function onTypeChange(e) {
formData.type=e
}
const handleSubmit = () => {
formRef.value?.validate()
@@ -177,26 +166,47 @@ const handleSubmit = () => {
let header={
'Authorization':uni.getStorageSync('Padmin-Token')
}
formData.goalPersonId=personInfo.value.goalPersonId
$api.myRequest('/dispatch/assist/records/addRecords', formData,'post',9100,header).then((resData) => {
console.log("resData",resData)
if(resData && resData.code == 200){
handleReset()
getFollowList()
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
});
}else{
uni.showToast({
title: resData.msg,
icon: 'none',
duration: 2000
});
}
});
console.log("formData",formData)
if(formData.id){
$api.myRequest('/dispatch/job/willingness', formData,'put',9100,header).then((resData) => {
if(resData && resData.code == 200){
handleReset()
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
});
uni.navigateBack()
}else{
uni.showToast({
title: resData.msg,
icon: 'none',
duration: 2000
});
}
});
}else{
$api.myRequest('/dispatch/job/willingness', formData,'post',9100,header).then((resData) => {
if(resData && resData.code == 200){
handleReset()
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
});
uni.navigateBack()
}else{
uni.showToast({
title: resData.msg,
icon: 'none',
duration: 2000
});
}
});
}
})
.catch((errors) => {
console.log('校验失败:', errors);
@@ -204,57 +214,35 @@ const handleSubmit = () => {
};
const handleReset = () => {
formData.followDate = '';
formData.followWay = '';
formData.content = '';
formData.result = '';
formData.nextPlan = '';
formData.nextContactDate = '';
formData.postType=''
formData.salary=''
formData.regionId=''
formData.regionName=''
formData.description=''
formData.welfare=''
formData.education=''
formData.jobType=''
formData.type=''
}
onLoad((options) => {
personInfo.value.goalPersonId=options.goalPersonId
personInfo.value.name=options.name
personInfo.value.task_type=options.taskType
personInfo.value.task_id=options.taskId
personInfo.value.person_id=options.personId
getDictionary()
getFollowList()
runAsyncTasks(options)
});
const runAsyncTasks = async (options) => {
await getDictionary()
if(options.goalPersonId){
formData.goalPersonId=options.goalPersonId
showTitle.value='新增'
}
if(options.item){
let dataInfo=JSON.parse(options.item)
Object.assign(formData, dataInfo)
showTitle.value='编辑'
}
}
</script>
<style lang="stylus" scoped>
image
height: 100%
width: 100%
.info-box
margin: 30rpx 30rpx
background: linear-gradient(0deg, #D9ECFF 0%, #F0F7FF 100%)
border-radius: 20rpx
padding: 40rpx 0
display: flex
align-items: center
.info-img
width: 40rpx
height: 40rpx
margin-bottom: 20rpx
.info-line
border-right: 2rpx solid #B7D6FF
.info-item
display: flex
flex-direction: column
align-items: center
justify-content: center
width: 50%
.info-label
font-size: 26rpx
color: #6E7E9B
margin-bottom: 20rpx
.info-value
font-weight: bold
font-size: 28rpx
color: #3D61AC
.main-list
background-color: #ffffff
padding: 20rpx 20rpx 28rpx 20rpx
@@ -279,34 +267,13 @@ image
height: 8rpx
background: linear-gradient(90deg, #FFAD58 0%, #FF7A5B 100%)
border-radius: 4rpx
.title-total
font-size: 24rpx
color: #999999
.total-num
color: #3088FF
margin-left: 4rpx
margin-right: 4rpx
font-weight: bold
font-size: 26rpx
.label
width: 160rpx
font-size: 28rpx
color: #404040
.input,
.picker
flex: 1
.picker-value
color: #666
.list-box
margin-top: 40rpx
.form-container
margin-top: 30rpx
:deep(.uni-forms-item__label)
width: 194rpx !important
width: 235rpx !important
font-size: 28rpx;
color: #404040;
@@ -332,35 +299,4 @@ image
background-color: #368BFF;
color: white;
}
:deep(.uni-steps__column-circle )
width: 24rpx !important
height: 24rpx !important
background: radial-gradient(circle,
#00C0FA 0%,
#015EEA 50%,
#FFFFFF 51%,
#FFFFFF 100%) !important
border-radius: 50%
border: 2rpx solid #015EEA
:deep(.uni-steps__column-title)
font-size: 28rpx !important
color: #006CFF !important
margin-bottom: 24rpx
:deep(.uni-steps__column-desc)
font-size: 28rpx
color: #898989 !important
line-height: 1.5
:deep(.uni-steps__column-text )
padding: 16rpx 0 !important
border: none
:deep(.uni-steps__column-line)
background-color: #368BFF !important
:deep(.uni-steps__column-line--before)
background-color:rgba(0,0,0,0) !important
:deep(.uni-date-x)
background: rgba(0,0,0,0) !important
:deep(.uni-stat-box)
background: rgba(0,0,0,0) !important
:deep(.uni-easyinput__content)
background: rgba(0,0,0,0) !important
</style>

View File

@@ -44,7 +44,7 @@
帮扶率
</view>
<view class="info-value">
{{ stats.assistRate }}
{{ stats.assistRate }}%
</view>
</view>
</view>
@@ -202,14 +202,20 @@
<button class="action-btn btn-success" size="mini" @click="goFollow(item)">跟进</button>
<button class="action-btn btn-gradient" size="mini" @click="goRecommend(item)">智能推荐</button>
<button class="action-btn btn-info" size="mini" @click="goJobWill(item)">求职意愿</button>
<button class="action-btn btn-info" size="mini" @click="goTarget(item)">培训意愿</button>
<button class="action-btn btn-warning" size="mini" v-if="!item.create_by_name" @click="goTarget(item)">退回</button>
<button class="action-btn btn-info" size="mini" @click="goTrainingWill(item)">培训意愿</button>
<button class="action-btn btn-warning" size="mini" v-if="!item.create_by_name" @click="returnItem(item)">退回</button>
</view>
</view>
</view>
<empty v-else pdTop="200"></empty>
</view>
</scroll-view>
<view>
<!-- 提示窗示例 -->
<uni-popup ref="alertDialog" type="dialog">
<uni-popup-dialog type="warn" cancelText="取消" confirmText="确定" title="系统提示" content="是否确认退回?" @confirm="dialogConfirm"></uni-popup-dialog>
</uni-popup>
</view>
</view>
</AppLayout>
</template>
@@ -240,6 +246,8 @@ const taskTypeOptions=ref([])
const priorityOptions=ref([])
const allocationStatusOptions=ref([])
const executeDeptOptions=ref([])
const alertDialog = ref(null);
const currentItem = ref({})
const baseUrl = config.imgBaseUrl
const getBackgroundStyle = (imageName) => ({
backgroundImage: `url(${baseUrl}/dispatch/${imageName})`,
@@ -379,13 +387,35 @@ function goFollow(item){
navTo('/packageB/priority/recordFollow?name='+item.name+'&taskType='+item.task_type+'&taskId='+item.task_id+'&personId='+item.person_id+'&goalPersonId='+item.goal_person_id);
}
function goRecommend(item){
navTo('/packageB/priority/allocate?item='+JSON.stringify(item)+'&url=taskIssue');
navTo('/packageB/priority/smartRecommend');
}
function goJobWill(item){
navTo('/packageB/priority/jobWill?id='+item.person_id+'&goalPersonId='+item.goal_person_id);
}
function goTarget(item){
navTo('/packageB/priority/targetPersonnel?id='+item.taskAllocation.id+'&taskName='+item.taskName);
function goTrainingWill(item){
navTo('/packageB/priority/trainingWill?id='+item.person_id+'&goalPersonId='+item.goal_person_id);
}
function returnItem(item){
if (alertDialog.value) {
alertDialog.value.open();
currentItem.value=item
}
}
function dialogConfirm(){
let header={
'Authorization':uni.getStorageSync('Padmin-Token')
}
let params={
goalPersonId:currentItem.value.goal_person_id
}
$api.myRequest('/dispatch/assist/records/returnRecords',params,'post',9100,header).then((resData) => {
if(resData.code==200){
dataList.value=[]
formData.pageNum=1
getDataList()
}
});
}
function scrollBottom(){
if(formData.pageNum<totalNum.value/formData.pageSize){

View File

@@ -0,0 +1,321 @@
<template>
<AppLayout :title="title" :show-bg-image="false" >
<view class="tab-list" >
<view class="tab" :class="{active: activeType == 1}" >求职<br>需求
</view>
<view class="tab" :class="{active: activeType == 2}" >创业<br>需求
</view>
<view class="tab" :class="{active: activeType == 3}" >培训<br>需求
</view>
<view class="tab" :class="{active: activeType == 4}" >其他<br>需求
</view>
</view>
<view class="main-list" :style="getBackgroundStyle('k.png')">
<view class="list-top">
<view class="list-title">
<text>帮扶记录详情</text>
<view class="title-line"></view>
</view>
</view>
<view class="form-container">
<view class="form-item">
<view class="item-label">
人员姓名
</view>
<view class="item-value">
{{formData.name}}
</view>
</view>
<view class="form-item">
<view class="item-label">
身份证号
</view>
<view class="item-value">
{{formData.id_card}}
</view>
</view>
<view class="form-item">
<view class="item-label">
联系电话
</view>
<view class="item-value">
{{formData.phone}}
</view>
</view>
<view class="form-item">
<view class="item-label">
帮扶类型
</view>
<view class="item-value">
{{formData.task_type}}
</view>
</view>
<view class="form-item">
<view class="item-label">
帮扶人员
</view>
<view class="item-value" >
{{formData.create_by_name}}
</view>
</view>
<view class="form-item">
<view class="item-label">
帮扶日期
</view>
<view class="item-value">
{{formData.follow_date}}
</view>
</view>
<view class="form-item">
<view class="item-label">
下次联系
</view>
<view class="item-value">
{{formData.next_contact_date}}
</view>
</view>
<view class="form-item">
<view class="item-label">
人员标签
</view>
<view class="item-value">
{{formData.tag_name}}
</view>
</view>
<view class="form-item">
<view class="item-label">
帮扶内容
</view>
<view class="item-value">
{{formData.detailRecords}}
</view>
</view>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { inject, ref, reactive,onMounted } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
const { $api, navTo, navBack } = inject('globalFunction');
import config from "@/config.js"
const title = ref('');
const activeType = ref(1)
const formData = reactive({
taskName: '',
taskType: '',
priority: '',
createTime:'',
allocationStatus:'',
taskAllocation: {
goalPersonCount: null,
executeDeptId: '',
executeDeptName: '',
executeDeptAncestors: '',
allocationStatus: '1',
allocationNote: '',
deadline: null,
goalPersonList: []
}
})
const taskTypeOptions=ref([])
const priorityOptions=ref([])
const allocationStatusOptions=ref([])
const executeDeptOptions=ref([])
// 表单引用
const formRef = ref(null)
const baseUrl = config.imgBaseUrl
const getBackgroundStyle = (imageName) => ({
backgroundImage: `url(${baseUrl}/dispatch/${imageName})`,
backgroundSize: 'cover', // 覆盖整个容器
backgroundPosition: 'center', // 居中
backgroundRepeat: 'no-repeat'
});
function getDictionary(){
$api.myRequest('/system/public/dict/data/type/assist_task_type').then((resData) => {
if(resData && resData.code == 200){
resData.data.forEach(item=>{
const obj = {
value: item.dictValue,
text: item.dictLabel
}
taskTypeOptions.value.push(obj)
})
}
});
}
function getDetail(id){
let header={
'Authorization':uni.getStorageSync('Padmin-Token'),
'Content-Type': "application/x-www-form-urlencoded"
}
let params={
goalPersonId:id
}
$api.myRequest('/dispatch/assist/records/getDetail',params,'get',9100,header).then((resData) => {
console.log("resData",resData)
resData.data.task_type=getabelByValue(resData.data.task_type,taskTypeOptions.value)
Object.assign(formData, resData.data)
});
}
function getabelByValue(value,arr) {
if (!Array.isArray(arr)) {
return ''
}
const item = arr.find(item => item.value === String(value))
return item ? item.text : '暂无'
}
onLoad((options) => {
runAsyncTasks(options)
});
const runAsyncTasks = async (options) => {
await getDictionary()
await getDetail(options.id)
}
</script>
<style lang="stylus" scoped>
.tab-list
display: flex
margin: 16rpx 30rpx 30rpx
text-align: center
border-radius: 16rpx
background: #fff
align-items: center
justify-content: space-between
.active
background: #1A62CE
color: #fff
position: relative
font-weight: bold
image
height: 100%
width: 100%
.main-list
background-color: #ffffff
padding: 20rpx 20rpx 28rpx 20rpx
margin: 30rpx 30rpx
box-shadow: 0px 3px 20px 0px rgba(0,105,234,0.1)
border-radius: 12px
.list-top
display: flex
align-items: center
justify-content: space-between
.list-title
font-weight: bold
font-size: 36rpx
color: #404040
position: relative
.title-line
position: absolute
bottom: -10rpx
left: 70rpx
width: 70rpx
height: 8rpx
background: linear-gradient(90deg, #FFAD58 0%, #FF7A5B 100%)
border-radius: 4rpx
.title-total
font-size: 24rpx
color: #999999
.total-num
color: #3088FF
margin-left: 4rpx
margin-right: 4rpx
font-weight: bold
font-size: 26rpx
.input,
.picker
flex: 1
.picker-value
color: #666
.form-container
margin-top: 30rpx
.con-box
background: #fff
padding: 20rpx
box-shadow: 0px 0px 6rpx 0px rgba(0,71,200,0.16)
border-radius: 24rpx
border: 1rpx solid #EDF5FF
margin-top: 30rpx
.form-item
display: flex
align-items: center
margin-bottom: 20rpx
.mb-30
margin-bottom: 30rpx
.item-left
display: flex
align-items: center
.item-img
width: 26rpx
height: 26rpx
margin-right: 10rpx
.item-label1
font-size: 26rpx
color: #B3B3B3
width: 130rpx
.item-label
width:200rpx
text-align: left
font-size: 30rpx
color: #606266
height: 72rpx
padding: 0 24rpx 0 0
vertical-align: middle
flex-shrink: 0
box-sizing: border-box
.item-value
color: #333
font-size: 30rpx
height: 72rpx
padding: 0 24rpx 0 0
vertical-align: middle
flex-shrink: 0
box-sizing: border-box
:deep(.uni-forms-item__label)
width: 194rpx !important
font-size: 28rpx;
color: #404040;
.button-group {
display: flex;
justify-content: space-between;
padding: 40rpx 20rpx 20rpx;
}
.btn {
width: 45%;
height: 80rpx;
font-size: 30rpx;
border-radius: 8rpx;
}
.reset-btn {
background-color: #D8E9FF;
color: #1176FF;
}
.submit-btn {
background-color: #368BFF;
color: white;
}
.choice-btn{
width: 100%;
height: 70rpx;
font-size: 28rpx;
border-radius: 8rpx;
background-color: #368BFF;
color: white;
margin-left: 0;
}
:deep(.uni-easyinput__content)
background: rgba(0,0,0,0) !important
</style>

View File

@@ -0,0 +1,451 @@
<template>
<AppLayout :title="title" :show-bg-image="false" >
<view class="page-container" >
<scroll-view :scroll-y="true" class="nearby-scroll" @scrolltolower="scrollBottom" lower-threshold="50">
<view class="main-list" :style="getBackgroundStyle('k.png')" >
<view class="list-top">
<view class="list-title">
<text>培训意愿列表</text>
<view class="title-line" style="left: 70rpx;"></view>
</view>
<view class="title-total">
<text class="total-num">{{totalNum}}</text>
</view>
</view>
<view class="list-box" v-if="dataList.length>0">
<view class="con-box" v-for="(item,index) in dataList" :key="index">
<view class="form-item">
<view class="item-left">
<image class="item-img" :src="baseUrl+'/dispatch/date.png'" mode=""></image>
<view class="item-label">
需求方向
</view>
</view>
<view class="item-right">
{{getabelByValue(item.demandDirection,trainNeedOptions)}}
</view>
</view>
<view class="form-item">
<view class="item-left">
<image class="item-img" :src="baseUrl+'/dispatch/date.png'" mode=""></image>
<view class="item-label">
授课方式
</view>
</view>
<view class="item-right">
{{getabelByValue(item.courseWay,classMethodOptions)}}
</view>
</view>
<view class="form-item">
<view class="item-left">
<image class="item-img" :src="baseUrl+'/dispatch/date.png'" mode=""></image>
<view class="item-label">
课程类型
</view>
</view>
<view class="item-right">
{{getabelByValue(item.courseType,questionClassificationOptions)}}
</view>
</view>
<view class="form-item" >
<view class="item-left">
<image class="item-img" :src="baseUrl+'/dispatch/person.png'" mode=""></image>
<view class="item-label">
培训时间
</view>
</view>
<view class="item-right">
{{item.trainDate}}
</view>
</view>
<view class="form-item">
<view class="item-left">
<image class="item-img" :src="baseUrl+'/dispatch/help.png'" mode=""></image>
<view class="item-label">
培训地点
</view>
</view>
<view class="item-right">
{{item.trainAddress}}
</view>
</view>
<view class="form-item" >
<view class="item-left">
<image class="item-img" :src="baseUrl+'/dispatch/base.png'" mode=""></image>
<view class="item-label">
费用预算
</view>
</view>
<view class="item-right">
{{item.trainFee}}
</view>
</view>
<view class="form-btns">
<button class="mini-btn form-box-btn detail-btn" size="mini" @click="goDetail('edit',item)">编辑</button>
<button class="mini-btn form-box-btn follow-btn" size="mini" @click="del(item)">删除</button>
</view>
</view>
</view>
<empty v-else pdTop="200"></empty>
</view>
</scroll-view>
<view class="float-btn" @click="goDetail('add')">
<uni-icons type="plusempty" color="#fff" size="30"></uni-icons>
</view>
<view>
<!-- 提示窗示例 -->
<uni-popup ref="alertDialog" type="dialog">
<uni-popup-dialog type="warn" cancelText="取消" confirmText="确定" title="提示" content="确定要删除这条求职意愿吗?" @confirm="dialogConfirm"></uni-popup-dialog>
</uni-popup>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { inject, ref, reactive, onMounted } from 'vue';
import { onLoad,onShow } from '@dcloudio/uni-app';
const { $api, navTo, navBack } = inject('globalFunction');
import config from "@/config.js"
const title = ref('');
const id=ref('')
const pageNum = ref(1)
const pageSize = ref(2)
const totalNum=ref(0)
const dataList=ref([])
const trainNeedOptions=ref([])
const classMethodOptions=ref([])
const questionClassificationOptions=ref([])
const goalPersonId=ref([])
const baseUrl = config.imgBaseUrl
const getBackgroundStyle = (imageName) => ({
backgroundImage: `url(${baseUrl}/dispatch/${imageName})`,
backgroundSize: 'cover', // 覆盖整个容器
backgroundPosition: 'center', // 居中
backgroundRepeat: 'no-repeat'
});
const alertDialog = ref(null);
const currentItem=ref({})
function getDictionary(){
$api.myRequest('/system/public/dict/data/type/train_need').then((resData) => {
if(resData && resData.code == 200){
resData.data.forEach(item=>{
const obj = {
value: item.dictValue,
text: item.dictLabel
}
trainNeedOptions.value.push(obj)
})
}
});
$api.myRequest('/system/public/dict/data/type/class_method').then((resData) => {
if(resData && resData.code == 200){
resData.data.forEach(item=>{
const obj = {
value: item.dictValue,
text: item.dictLabel
}
classMethodOptions.value.push(obj)
})
}
});
$api.myRequest('/system/public/dict/data/type/question_classification').then((resData) => {
if(resData && resData.code == 200){
resData.data.forEach(item=>{
const obj = {
value: item.dictValue,
text: item.dictLabel
}
questionClassificationOptions.value.push(obj)
})
}
});
}
function getabelByValue(value,arr) {
if (!Array.isArray(arr)) {
return ''
}
const item = arr.find(item => item.value === String(value))
return item ? item.text : '暂无'
}
function getDataList(){
let header={
'Authorization':uni.getStorageSync('Padmin-Token'),
'Content-Type': "application/x-www-form-urlencoded"
}
let params={
personId: id.value,
pageNum: pageNum.value,
pageSize: pageSize.value
}
$api.myRequest('/dispatch/train/willingness/list',params,'get',9100,header).then((resData) => {
totalNum.value=resData.total
dataList.value=dataList.value.concat(resData.rows)
});
}
function scrollBottom(){
if(pageNum.value<totalNum.value/pageSize.value){
pageNum.value++
getDataList()
}
}
function goDetail(val,item){
if(val=='add'){
navTo('/packageB/priority/trainingWillEdit?goalPersonId=' + goalPersonId.value);
}else{
navTo('/packageB/priority/trainingWillEdit?item=' + JSON.stringify(item));
}
}
function del(item){
if (alertDialog.value) {
alertDialog.value.open();
currentItem.value=item
}
}
function dialogConfirm(){
let header={
'Authorization':uni.getStorageSync('Padmin-Token'),
'Content-Type': "application/x-www-form-urlencoded"
}
$api.myRequest('/dispatch/train/willingness/'+currentItem.value.id,{},'delete',9100,header).then((resData) => {
if(resData.code==200){
dataList.value=[]
pageNum.value=1
getDataList()
}
});
}
onLoad((options) => {
id.value=options.id
goalPersonId.value=options.goalPersonId
});
const runAsyncTasks = async () => {
await getDictionary()
await getDataList()
}
onShow(()=>{
dataList.value=[]
pageNum.value=1
runAsyncTasks()
})
</script>
<style lang="stylus" scoped>
image
height: 100%
width: 100%
.page-container {
display: flex;
flex-direction: column;
height: calc(100vh - var(--window-top)); /* 如果 AppLayout 有 header需减去 */
/* 或者简单用height: 100vh; */
padding-bottom: 140rpx
}
.nearby-scroll
// 使用flex布局让scroll-view自适应高度占据剩余空间
flex: 1
// overflow: hidden;
.task-box
display: flex
align-items: center
.task-label
font-size: 30rpx
color: #6E7E9B
.task-name
font-weight: bold
font-size: 30rpx
color: #3D61AC
.main-list
background-color: #ffffff
padding: 20rpx 20rpx 28rpx 20rpx
margin: 30rpx 30rpx
box-shadow: 0px 3px 20px 0px rgba(0,105,234,0.1)
border-radius: 12px
.list-top
display: flex
align-items: center
justify-content: space-between
.list-title
font-weight: bold
font-size: 36rpx
color: #404040
position: relative
.title-line
position: absolute
bottom: -10rpx
left: 70rpx
width: 70rpx
height: 8rpx
background: linear-gradient(90deg, #FFAD58 0%, #FF7A5B 100%)
border-radius: 4rpx
.title-total
font-size: 24rpx
color: #999999
.total-num
color: #3088FF
margin-left: 4rpx
margin-right: 4rpx
font-weight: bold
font-size: 26rpx
.list-box
margin-top: 40rpx
:deep(.uni-forms-item__label)
width: 194rpx !important
font-size: 28rpx;
color: #404040;
.search-container
padding: 20rpx 0rpx 0rpx 0rpx
.title-total
font-size: 24rpx
color: #999999
.total-num
color: #3088FF
margin-left: 4rpx
margin-right: 4rpx
font-weight: bold
font-size: 26rpx
.search-item
display: flex
align-items: center
margin-bottom: 30rpx
.label
width: 160rpx
font-size: 28rpx
color: #404040
flex-shrink: 0
.input,
.picker
background: #FFFFFF
flex: 1
min-width: 0
.search-box-btn
border-radius: 32rpx !important
background: #3088FF !important
margin-right: 16rpx
.reset-box-btn
border-radius: 32rpx !important
background: #02B44D
color: #fff
.con-box
background: #fff
padding: 20rpx
box-shadow: 0px 0px 6rpx 0px rgba(0,71,200,0.16)
border-radius: 24rpx
border: 1rpx solid #EDF5FF
margin-top: 30rpx
.form-title
display: flex
align-items: center
.form-name
font-weight: bold
font-size: 30rpx
color: #595959
margin-right:16rpx
.form-type
border-radius: 8rpx;
border: 2rpx solid #FF7D26;
font-size: 24rpx
color: #F1690E
padding: 4rpx 10rpx
.form-item
display: flex
align-items: center
justify-content: space-between
margin-top: 30rpx
.item-left
display: flex
align-items: center
.item-img
width: 26rpx
height: 26rpx
margin-right: 10rpx
.item-label
font-size: 26rpx
color: #B3B3B3
width: 190rpx
.item-right
font-size: 26rpx
color: #737373
// overflow: hidden
// text-overflow: ellipsis
// white-space: nowrap
word-wrap: break-word
overflow-wrap: break-word
white-space: normal
.form-btns
margin-top:30rpx
.form-box-btn
border-radius: 50rpx !important
margin-right: 24rpx
padding: 0rpx 40rpx
.detail-btn
background: #EDF5FF
border: 1px solid #3088FF
font-size: 28rpx
color: #3088FF
.follow-btn
background: #EEF9F3
border: 1px solid #00933E
font-size: 28rpx
color: #00933E
.recommend-btn
background: linear-gradient(92deg, #0DCCFF 0%, #4760FF 100%)
font-size: 28rpx
color: #FFFFFF
.button-group
position: fixed
bottom: 0
left: 0
width: 100%
height: 120rpx
background: #fff
.btns
height: 120rpx
width: 100%
line-height: 120px
display: flex
align-items: center
justify-content: space-between
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1)
.btn {
width: 45%;
height: 80rpx;
font-size: 30rpx;
border-radius: 8rpx;
}
.reset-btn {
background-color: #D8E9FF;
color: #1176FF;
}
.submit-btn {
background-color: #368BFF;
color: white;
}
.float-btn{
position: fixed;
bottom: 100rpx;
right: 50rpx;
background: #368BFF;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
line-height: 100rpx;
text-align: center;
color: #fff;
}
</style>

View File

@@ -0,0 +1,312 @@
<template>
<AppLayout :title="title" :show-bg-image="false" >
<view class="main-list" :style="getBackgroundStyle('k.png')">
<view class="list-top">
<view class="list-title">
<text>{{showTitle}}培训意愿</text>
<view class="title-line"></view>
</view>
</view>
<view class="form-container">
<uni-forms ref="formRef" v-model="formData" :rules="rules" validate-trigger="submit" >
<uni-forms-item label="需求方向:" name="demandDirection" required >
<uni-data-select v-model="formData.demandDirection" placeholder="请选择需求方向" :localdata="trainNeedOptions" @change="onTrainNeedChange"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="授课方式:" name="courseWay" required>
<uni-data-select v-model="formData.courseWay" placeholder="请选择授课方式" :localdata="classMethodOptions" @change="onClassMethodChange"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="课程类型:" name="courseType" required >
<uni-data-select v-model="formData.courseType" placeholder="请选择课程类型" :localdata="questionClassificationOptions" @change="onQuestionClassificationChange"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="培训时间:" name="trainDate" required>
<uni-datetime-picker type="date" placeholder="请选择培训时间" v-model="formData.trainDate" @maskClick="onTrainDateChange" />
</uni-forms-item>
<uni-forms-item label="培训费用预算:" name="trainFee" required>
<uni-easyinput v-model="formData.trainFee" placeholder="请输入培训费用预算"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="培训地点:" name="trainAddress" required>
<uni-easyinput v-model="formData.trainAddress" placeholder="请输入培训地点"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="培训目标:" name="trainGoal" required>
<uni-easyinput type="textarea" v-model="formData.trainGoal" placeholder="请输入培训目标"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="建议与意见:" name="opinions" >
<uni-easyinput type="textarea" v-model="formData.opinions" placeholder="请输入建议与意见"></uni-easyinput>
</uni-forms-item>
</uni-forms>
<!-- 按钮组 -->
<view class="button-group">
<button class="btn submit-btn" @click="handleSubmit">保存跟进</button>
<button class="btn reset-btn" @click="handleReset">重置</button>
</view>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { inject, ref, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
const { $api, navTo, navBack } = inject('globalFunction');
import config from "@/config.js"
const title = ref('');
const showTitle=ref('')
const formData = reactive({
id: null,
goalPersonId: '',
demandDirection: '',
trainDate: '',
trainAddress: '',
trainFee: '',
courseWay: '',
courseType: '',
trainGoal: '',
opinions: ''
})
const trainNeedOptions=ref([])
const classMethodOptions=ref([])
const questionClassificationOptions=ref([])
// 表单引用
const formRef = ref(null)
// 校验规则
const rules = {
demandDirection: {
rules: [{
required: true,
errorMessage: '请选择需求方向'
}]
},
courseWay: {
rules: [{
required: true,
errorMessage: '请选择授课方式'
}]
},
courseType: {
rules: [{
required: true,
errorMessage: '请选择课程类型'
}]
},
trainDate: {
rules: [{
required: true,
errorMessage: '请选择培训时间'
}]
},
trainFee: {
rules: [{
required: true,
errorMessage: '请输入培训费用预算'
}]
},
trainAddress: {
rules: [{
required: true,
errorMessage: '请输入培训地点'
}]
},
trainGoal: {
rules: [{
required: true,
errorMessage: '请输入培训目标'
}]
}
}
const baseUrl = config.imgBaseUrl
const getBackgroundStyle = (imageName) => ({
backgroundImage: `url(${baseUrl}/dispatch/${imageName})`,
backgroundSize: 'cover', // 覆盖整个容器
backgroundPosition: 'center', // 居中
backgroundRepeat: 'no-repeat'
});
const getDictionary = async () => {
try {
const [trainRes, classRes, questionRes] = await Promise.all([
$api.myRequest('/system/public/dict/data/type/train_need'),
$api.myRequest('/system/public/dict/data/type/class_method'),
$api.myRequest('/system/public/dict/data/type/question_classification')
]);
if (trainRes && trainRes.code == 200) {
trainRes.data.forEach(item => {
trainNeedOptions.value.push({
value: item.dictValue,
text: item.dictLabel
});
});
}
if (classRes && classRes.code == 200) {
classRes.data.forEach(item => {
classMethodOptions.value.push({
value: item.dictValue,
text: item.dictLabel
});
});
}
if (questionRes && questionRes.code == 200) {
questionRes.data.forEach(item => {
questionClassificationOptions.value.push({
value: item.dictValue,
text: item.dictLabel
});
});
}
} catch (error) {
console.error("获取字典数据失败:", error);
throw error; // 抛出错误,让外部调用者知道失败了
}
};
function onTrainNeedChange(e){
formData.demandDirection=e
}
function onClassMethodChange(e){
formData.courseWay=e
}
function onQuestionClassificationChange(e) {
formData.courseType=e
}
function onTrainDateChange(e){
formData.trainDate=e
}
const handleSubmit = () => {
formRef.value?.validate()
.then(() => {
let header={
'Authorization':uni.getStorageSync('Padmin-Token')
}
if(formData.id){
$api.myRequest('/dispatch/train/willingness', formData,'put',9100,header).then((resData) => {
if(resData && resData.code == 200){
handleReset()
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
});
uni.navigateBack()
}else{
uni.showToast({
title: resData.msg,
icon: 'none',
duration: 2000
});
}
});
}else{
$api.myRequest('/dispatch/train/willingness', formData,'post',9100,header).then((resData) => {
if(resData && resData.code == 200){
handleReset()
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
});
uni.navigateBack()
}else{
uni.showToast({
title: resData.msg,
icon: 'none',
duration: 2000
});
}
});
}
})
.catch((errors) => {
console.log('校验失败:', errors);
});
};
const handleReset = () => {
formData.demandDirection=''
formData.trainDate=''
formData.trainAddress=''
formData.trainFee=''
formData.courseWay=''
formData.courseType=''
formData.trainGoal=''
formData.opinions=''
}
onLoad((options) => {
runAsyncTasks(options)
});
const runAsyncTasks = async (options) => {
await getDictionary()
if(options.goalPersonId){
formData.goalPersonId=options.goalPersonId
showTitle.value='新增'
}
if(options.item){
let dataInfo=JSON.parse(options.item)
Object.assign(formData, dataInfo)
showTitle.value='编辑'
}
}
</script>
<style lang="stylus" scoped>
.main-list
background-color: #ffffff
padding: 20rpx 20rpx 28rpx 20rpx
margin: 30rpx 30rpx
box-shadow: 0px 3px 20px 0px rgba(0,105,234,0.1)
border-radius: 12px
.list-top
display: flex
align-items: center
justify-content: space-between
.list-title
font-weight: bold
font-size: 36rpx
color: #404040
position: relative
.title-line
position: absolute
bottom: -10rpx
left: 70rpx
width: 70rpx
height: 8rpx
background: linear-gradient(90deg, #FFAD58 0%, #FF7A5B 100%)
border-radius: 4rpx
.input,
.picker
flex: 1
.form-container
margin-top: 30rpx
:deep(.uni-forms-item__label)
width: 235rpx !important
font-size: 28rpx;
color: #404040;
.button-group {
display: flex;
justify-content: space-between;
padding: 40rpx 20rpx 20rpx;
}
.btn {
width: 45%;
height: 80rpx;
font-size: 30rpx;
border-radius: 8rpx;
}
.reset-btn {
background-color: #D8E9FF;
color: #1176FF;
}
.submit-btn {
background-color: #368BFF;
color: white;
}
</style>

View File

@@ -502,7 +502,25 @@
{
"path": "priority/jobWillEdit",
"style": {
"navigationBarTitleText": "编辑求职意愿"
"navigationBarTitleText": "求职意愿"
}
},
{
"path": "priority/trainingWill",
"style": {
"navigationBarTitleText": "培训意愿列表"
}
},
{
"path": "priority/trainingWillEdit",
"style": {
"navigationBarTitleText": "培训意愿"
}
},
{
"path": "priority/smartRecommend",
"style": {
"navigationBarTitleText": "智能推荐"
}
},
{