通知公告

This commit is contained in:
2026-01-16 16:50:06 +08:00
parent d6b6fdcc38
commit d983bb272b
3 changed files with 259 additions and 373 deletions

View File

@@ -0,0 +1,79 @@
<template>
<AppLayout :show-bg-image="false">
<view class="main-list" >
<view class="title">
{{ dataInfo.title }}
</view>
<view class="publishTime">
发布日期{{ dataInfo.publishTime }}
</view>
<view >
<view class="gk-l-i-bottom" v-html="dataInfo.content"></view>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { inject, ref, reactive, onMounted } from "vue";
import { onLoad, onShow } from '@dcloudio/uni-app';
const { $api, navTo, navBack, vacanciesTo } = inject("globalFunction");
import config from "@/config.js";
import AppLayout from "@/components/AppLayout/AppLayout.vue";
const baseUrl = config.imgBaseUrl;
const dataInfo = ref([]);
const id = ref('');
const getBackgroundStyle = (imageName) => ({
backgroundImage: `url(${baseUrl}/${imageName})`,
backgroundSize: "cover", // 覆盖整个容器
backgroundPosition: "center", // 居中
backgroundRepeat: "no-repeat",
});
onLoad((options) => {
id.value=options.id
getData();
});
function getData() {
let params={
id:id.value
}
$api.myRequest('/train/public/announcement/selectById', params).then((resData) => {
if(resData.code==200){
var td = new RegExp("<td", "g")
var table = new RegExp('<table style="width: auto;', "g")
resData.data.content = (resData.data.content + "").replace(td, '<td style = "border:1px solid #cecece;font-size:0.8rem;" ')
resData.data.content = (resData.data.content + "").replace(table, '<table style="width: auto; border-collapse: collapse;" ')
dataInfo.value=resData.data
}
});
}
</script>
<style lang="scss" scoped>
.main-list {
background-color: #ffffff;
padding: 20rpx 25rpx 28rpx 25rpx;
margin: 30rpx 30rpx;
box-shadow: 0px 3px 20px 0px rgba(0, 105, 234, 0.1);
border-radius: 12px;
}
.title {
font-size: 32rpx;
font-weight: bold;
color: #282828;
margin-bottom: 16rpx;
display: flex;
justify-content: center;
}
.publishTime{
text-align: center;
font-size: 24rpx;
color: #a2a2a2;
margin-top: 12rpx;
margin-bottom: 20rpx;
}
</style>

View File

@@ -1,400 +1,201 @@
<template> <template>
<AppLayout :title="title" :show-bg-image="false" > <AppLayout :title="title" :show-bg-image="false">
<view class="info-box"> <view class="tab-container">
<view class="info-item info-line"> <view class="tab-item" :class="{ active: currentTab === 'train' }" @click="switchTab('train')">
<image class="info-img" :src="baseUrl+'/dispatch/person-icon.png'" mode=""></image> 培训公告
<view class="info-label">
人员姓名
</view>
<view class="info-value">
{{personInfo.name}}
</view>
</view>
<view class="info-item">
<image class="info-img" :src="baseUrl+'/dispatch/help-icon.png'" mode=""></image>
<view class="info-label">
帮扶类型
</view>
<view class="info-value">
{{personInfo.taskType}}
</view>
</view>
</view> </view>
<view class="main-list" :style="getBackgroundStyle('k.png')"> <view class="tab-item" :class="{ active: currentTab === 'evaluate' }" @click="switchTab('evaluate')">
<view class="list-top"> 评价公告
<view class="list-title">
<text>新增跟进记录</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="followDate" required >
<uni-datetime-picker class="picker-value" type="date" placeholder="请选择跟进日期" v-model="formData.followDate" @change="onFollowDateChange" />
</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>
<!-- 跟进内容 -->
<uni-forms-item label="跟进内容:" name="content" required>
<uni-easyinput type="textarea" v-model="formData.content" placeholder="请输入跟进内容"></uni-easyinput>
</uni-forms-item>
<!-- 跟进结果 -->
<uni-forms-item label="跟进结果:" name="result" required>
<uni-easyinput type="textarea" v-model="formData.result" placeholder="请输入跟进结果"></uni-easyinput>
</uni-forms-item>
<!-- 下一步计划 -->
<uni-forms-item label="下一步计划:" name="nextPlan">
<uni-easyinput type="textarea" v-model="formData.nextPlan" placeholder="请输入下一步计划(可选)"></uni-easyinput>
</uni-forms-item>
<!-- 下次联系时间 -->
<uni-forms-item label="下次联系:" name="nextContactDate" >
<uni-datetime-picker class="picker-value" type="date" placeholder="请选择跟进日期" v-model="formData.nextContactDate" @change="onDateChange" />
</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>
<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 class="title-total">
<text class="total-num">{{followListNum}}</text>条记录
</view>
</view>
<view class="list-box" v-if="followListNum>0">
<uni-steps :options="followList" active-color="#007AFF" :active="active" direction="column" />
</view>
<empty v-else pdTop="200"></empty>
</view> </view>
</AppLayout> </view>
<scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLower">
<view class="main-list" >
<view
:style="getBackgroundStyle('frame-activity.png')"
class="policy-list"
v-for="(item, index) in policyList"
:key="index"
@click="goPolicyDetail(item)" >
<view class="title">
{{ item.title }}
</view>
<view class="bottom-line">
<view>
<uni-icons color="#A2A2A2" type="info" size="12"></uni-icons>
发布日期{{ item.publishTime }}
</view>
</view>
<view >
<view class="gk-l-i-bottom" v-html="item.content"></view>
</view>
</view>
</view>
</scroll-view>
</AppLayout>
</template> </template>
<script setup> <script setup>
import { inject, ref, reactive } from 'vue'; import { inject, ref, reactive, onMounted } from "vue";
import { onLoad } from '@dcloudio/uni-app'; const { $api, navTo, navBack, vacanciesTo } = inject("globalFunction");
const { $api, navTo, navBack } = inject('globalFunction'); import config from "@/config.js";
import config from "@/config.js" import AppLayout from "@/components/AppLayout/AppLayout.vue";
const title = ref("");
const baseUrl = config.imgBaseUrl;
const pageSize=ref(10)
const pageNum=ref(1)
const totalNum=ref(0)
// Tab 控制
const currentTab = ref("train"); // 默认显示培训公告
const title = ref(''); function switchTab(tabName) {
const formData = reactive({ currentTab.value = tabName;
goalPersonId:'', getPolicyData('refresh',currentTab)
followDate: '',
followWay: '',
content: '',
result: '',
nextPlan: '',
nextContactDate: ''
})
const personInfo=ref({
goalPersonId:'',
name:'',
taskType:'',
task_id:''
})
const followWays = ref([])
const followList = ref([])
const followListNum=ref(0)
const active=ref(null)
// 表单引用
const formRef = ref(null)
// 校验规则
const rules = {
followDate: {
rules: [{
required: true,
errorMessage: '请选择跟进日期'
}]
},
followWay: {
rules: [{
required: true,
errorMessage: '请选择跟进方式'
}]
},
content: {
rules: [{
required: true,
errorMessage: '请填写跟进内容'
}]
},
result: {
rules: [{
required: true,
errorMessage: '请填写跟进结果'
}]
}
} }
const baseUrl = config.imgBaseUrl const handleScrollToLower = () => {
getPolicyData('add',currentTab);
};
const getBackgroundStyle = (imageName) => ({ const getBackgroundStyle = (imageName) => ({
backgroundImage: `url(${baseUrl}/dispatch/${imageName})`, backgroundImage: `url(${baseUrl}/${imageName})`,
backgroundSize: 'cover', // 覆盖整个容器 backgroundSize: "100% 100%", // 覆盖整个容器
backgroundPosition: 'center', // 居中 backgroundPosition: "center", // 居中
backgroundRepeat: 'no-repeat' backgroundRepeat: "no-repeat",
}); });
onMounted(() => {
const onFollowDateChange = (e)=>{ getPolicyData('refresh',currentTab);
formData.followDate=e });
} const policyList = ref([]);
const onMethodChange = (e) => { function getPolicyData(type = 'add',currentTab='train') {
formData.followWay=e let current=ref('1')
} if(currentTab.value=='train'){
// 事件处理 current.value='1'
const onDateChange = ( e) => { }else if(currentTab.value=='evaluate'){
formData.nextContactDate=e current.value='2'
}
function getFollowList(){
let header={
'Authorization':uni.getStorageSync('fourLevelLinkage-token'),
'Content-Type': "application/x-www-form-urlencoded"
} }
let params={ let maxPage=Math.ceil(totalNum.value/pageSize.value)
personId:personInfo.value.person_id, let params={}
taskId:personInfo.value.task_id if (type === 'refresh') {
} pageNum.value = 1;
$api.myRequest('/dispatch/assist/records/getFollowList', params,'get',9100,header).then((resData) => { params={
console.log("resData",resData) pageSize:pageSize.value,
if(resData && resData.code == 200){ pageNum:pageNum.value,
if(resData.data && resData.data.length>0){ type:current.value
followListNum.value=resData.data.length
resData.data.forEach(item=>{
const obj={
title:item.followDate,
desc:`跟进方式:${getFollowWaysLabelByValue(item.followWay)}\n跟进人${item.createByName}\n跟进内容${item.content}`
}
followList.value.push(obj)
})
}
} }
}); $api.myRequest('/train/public/announcement/list', params).then((resData) => {
} if(resData.code==200){
for(var i = 0;i<resData.rows.length;i++){
function getDictionary(){ resData.rows[i].content = resData.rows[i].content.replace(/<[^>]+>/g,"");
$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) policyList.value=resData.rows
}) totalNum.value=resData.total
}
});
}
function getFollowWaysLabelByValue(value) {
if (!Array.isArray(followWays.value)) {
return ''
}
const item = followWays.value.find(item => item.value === String(value))
return item ? item.text : '暂无跟进方式'
}
const handleSubmit = () => {
formRef.value?.validate()
.then(() => {
let header={
'Authorization':uni.getStorageSync('fourLevelLinkage-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()
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
});
}else{
uni.showToast({
title: resData.msg,
icon: 'none',
duration: 2000
});
} }
}); });
}) }
.catch((errors) => { if (type === 'add' && pageNum.value < maxPage) {
console.log('校验失败:', errors); pageNum.value += 1;
}); params={
}; pageSize:pageSize.value,
pageNum:pageNum.value,
const handleReset = () => { type:current.value
formData.followDate = ''; }
formData.followWay = ''; $api.myRequest('/train/public/announcement/list', params).then((resData) => {
formData.content = ''; if(resData.code==200){
formData.result = ''; for(var i = 0;i<resData.rows.length;i++){
formData.nextPlan = ''; resData.rows[i].content = resData.rows[i].content.replace(/<[^>]+>/g,"");
formData.nextContactDate = ''; }
policyList.value=policyList.value.concat(resData.rows)
totalNum.value=resData.total
}
});
}
} }
onLoad((options) => {
personInfo.value.person_id=options.person_id
personInfo.value.name=options.name
personInfo.value.taskType=options.taskType
personInfo.value.task_id=options.task_id
getDictionary()
getFollowList()
});
function goPolicyDetail(item) {
uni.navigateTo({
url:`/packageB/notice/detail?id=${item.id}`
// url: `/packageRc/pages/policy/policyDetail?id=${item.id}`
});
}
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
image .main-list {
height: 100% // background-color: #ffffff;
width: 100% // padding: 20rpx 25rpx 28rpx 25rpx;
.info-box margin: 0 30rpx 30rpx 30rpx;
margin: 30rpx 30rpx // box-shadow: 0px 3px 20px 0px rgba(0, 105, 234, 0.1);
background: linear-gradient(0deg, #D9ECFF 0%, #F0F7FF 100%) // border-radius: 12px;
border-radius: 20rpx }
padding: 40rpx 0 .tab-container {
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
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
.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
font-size: 28rpx;
color: #404040;
.button-group {
display: flex; display: flex;
justify-content: space-between;
padding: 40rpx 20rpx 20rpx;
}
.btn {
width: 45%;
height: 80rpx; height: 80rpx;
font-size: 30rpx; background-color: #fff;
border-radius: 8rpx; margin: 0 30rpx 20rpx;
border-radius: 12rpx;
overflow: hidden;
margin-top: 10rpx;
} }
.reset-btn { .tab-item {
background-color: #D8E9FF; flex: 1;
color: #1176FF; display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: #666;
transition: all 0.3s;
} }
.submit-btn { .tab-item.active {
background-color: #368BFF; background-color: #ffffff;
color: white; color: #4c6efb;
font-weight: bold;
// box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
border-bottom: 2rpx solid #4c6efb;
} }
:deep(.uni-steps__column-circle ) .gk-l-i-bottom{
width: 24rpx !important margin-top: 16px;
height: 24rpx !important overflow: hidden;
background: radial-gradient(circle, text-overflow: ellipsis;
#00C0FA 0%, display: -webkit-box;
#015EEA 50%, -webkit-line-clamp: 3;
#FFFFFF 51%, -webkit-box-orient: vertical;
#FFFFFF 100%) !important }
border-radius: 50% .main-scroll {
border: 2rpx solid #015EEA width: 100%;
:deep(.uni-steps__column-title) height: 90%;
font-size: 28rpx !important }
color: #006CFF !important
margin-bottom: 24rpx .policy-list {
:deep(.uni-steps__column-desc) width: 100%;
font-size: 28rpx margin: 0 auto;
color: #898989 !important color: #333333;
line-height: 1.5 border-radius: 24rpx;
:deep(.uni-steps__column-text ) background: #ffffff;
padding: 16rpx 0 !important margin-bottom: 24rpx;
border: none padding: 28rpx 22rpx;
:deep(.uni-steps__column-line) box-sizing: border-box;
background-color: #368BFF !important position: relative;
:deep(.uni-steps__column-line--before)
background-color:rgba(0,0,0,0) !important
:deep(.uni-date-x) .title {
background: rgba(0,0,0,0) !important font-size: 32rpx;
:deep(.uni-stat-box) font-weight: bold;
background: rgba(0,0,0,0) !important color: #282828;
:deep(.uni-easyinput__content) margin-bottom: 16rpx;
background: rgba(0,0,0,0) !important display: flex;
</style> }
.bottom-line {
display: flex;
justify-content: space-between;
font-size: 24rpx;
color: #a2a2a2;
margin-top: 12rpx;
}
}
</style>

View File

@@ -426,6 +426,12 @@
"navigationBarTitleText": "培训评价公告" "navigationBarTitleText": "培训评价公告"
} }
}, },
{
"path": "notice/detail",
"style": {
"navigationBarTitleText": "公告详情"
}
},
{ {
"path": "institution/evaluationAgency", "path": "institution/evaluationAgency",
"style": { "style": {