调整教师请假的处理逻辑
This commit is contained in:
parent
4648a0793a
commit
cf832cc3d3
@ -91,13 +91,6 @@ export const findQjListApi = async (params: any) => {
|
||||
return await get("/api/jsQj/findPage", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据规则ID获取默认审批人和抄送人
|
||||
*/
|
||||
export const getApproversByRuleId = async (ruleId: string) => {
|
||||
return await get("/api/jsQj/getApproversByRuleId", { ruleId });
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据ID获取请假详情
|
||||
*/
|
||||
|
||||
@ -2,6 +2,14 @@ import { get, post } from "@/utils/request";
|
||||
|
||||
// 流程审批相关API接口
|
||||
|
||||
|
||||
/**
|
||||
* 根据规则ID获取默认审批人和抄送人
|
||||
*/
|
||||
export const getSprAndCsrByRuleId = async (ruleId: string) => {
|
||||
return await get("/api/lcglSet/getSprAndCsrByRuleId", { ruleId });
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据业务ID和业务类型获取审批流程
|
||||
* @param ywId 业务ID
|
||||
|
||||
@ -3,19 +3,11 @@
|
||||
<!-- 审批人列表 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">审批人</text>
|
||||
<text class="section-title">审批人({{ approvers.length || 0 }})</text>
|
||||
<!-- 审批人选择器 -->
|
||||
<BasicJsPicker
|
||||
ref="approverPickerRef"
|
||||
:customTrigger="true"
|
||||
:multiple="true"
|
||||
:excludeIds="getExcludeApproverIds()"
|
||||
:defaultValue="[]"
|
||||
title="选择审批人"
|
||||
placeholder="请选择审批人"
|
||||
searchPlaceholder="搜索审批人"
|
||||
@change="handleApproverChange"
|
||||
>
|
||||
<BasicJsPicker ref="approverPickerRef" :customTrigger="true" :multiple="true"
|
||||
:excludeIds="getExcludeApproverIds()" :defaultValue="[]" title="选择审批人" placeholder="请选择审批人"
|
||||
searchPlaceholder="搜索审批人" @change="handleApproverChange">
|
||||
<template #trigger>
|
||||
<view class="add-btn">
|
||||
<text class="add-icon">+</text>
|
||||
@ -29,36 +21,19 @@
|
||||
<view v-for="(spr, index) in approvers" :key="spr.id" class="list-item">
|
||||
<view class="item-info">
|
||||
<text class="item-name">{{ spr.jsxm }}</text>
|
||||
</view>
|
||||
<view class="item-actions">
|
||||
</view>
|
||||
<view class="item-actions" v-if="!spr.fixed">
|
||||
<!-- 上移箭头 -->
|
||||
<uni-icons
|
||||
v-if="index > 0"
|
||||
type="top"
|
||||
size="18"
|
||||
color="#666"
|
||||
@click="moveApproverUp(index)"
|
||||
class="action-icon"
|
||||
></uni-icons>
|
||||
|
||||
<uni-icons v-if="index > configSprList.length" type="top" size="18" color="#666" @click="moveApproverUp(index)"
|
||||
class="action-icon"></uni-icons>
|
||||
|
||||
<!-- 下移箭头 -->
|
||||
<uni-icons
|
||||
v-if="index < approvers.length - 1"
|
||||
type="bottom"
|
||||
size="18"
|
||||
color="#666"
|
||||
@click="moveApproverDown(index)"
|
||||
class="action-icon"
|
||||
></uni-icons>
|
||||
|
||||
<uni-icons v-if="index < approvers.length - 1" type="bottom" size="18" color="#666"
|
||||
@click="moveApproverDown(index)" class="action-icon"></uni-icons>
|
||||
|
||||
<!-- 删除图标改为垃圾桶图标 -->
|
||||
<uni-icons
|
||||
type="trash"
|
||||
size="18"
|
||||
color="#666"
|
||||
@click="removeApprover(index)"
|
||||
class="action-icon"
|
||||
></uni-icons>
|
||||
<uni-icons type="trash" size="18" color="#666" @click="removeApprover(index)"
|
||||
class="action-icon"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -71,19 +46,10 @@
|
||||
<!-- 抄送人列表 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">抄送人</text>
|
||||
<text class="section-title">抄送人({{ ccList.length || 0 }})</text>
|
||||
<!-- 抄送人选择器 -->
|
||||
<BasicJsPicker
|
||||
ref="ccPickerRef"
|
||||
:customTrigger="true"
|
||||
:multiple="true"
|
||||
:excludeIds="getExcludeCcIds()"
|
||||
:defaultValue="[]"
|
||||
title="选择抄送人"
|
||||
placeholder="请选择抄送人"
|
||||
searchPlaceholder="搜索抄送人"
|
||||
@change="handleCcChange"
|
||||
>
|
||||
<BasicJsPicker ref="ccPickerRef" :customTrigger="true" :multiple="true" :excludeIds="getExcludeCcIds()"
|
||||
:defaultValue="[]" title="选择抄送人" placeholder="请选择抄送人" searchPlaceholder="搜索抄送人" @change="handleCcChange">
|
||||
<template #trigger>
|
||||
<view class="add-btn">
|
||||
<text class="add-icon">+</text>
|
||||
@ -94,15 +60,21 @@
|
||||
</view>
|
||||
|
||||
<view class="list-content">
|
||||
<view v-for="(csr, index) in ccList" :key="csr.id" class="list-item">
|
||||
<view v-for="(csr, index) in displayedCsrList" :key="csr.id" class="list-item">
|
||||
<view class="item-info">
|
||||
<text class="item-name">{{ csr.jsxm }}</text>
|
||||
</view>
|
||||
<view class="item-actions">
|
||||
<view class="item-actions" v-if="!csr.fixed">
|
||||
<text class="delete-btn" @click="removeCc(index)">删除</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 更多按钮 -->
|
||||
<view v-if="ccList.length > 2" class="more-button" @click="toggleCsrExpanded">
|
||||
<text class="more-text">
|
||||
{{ csrExpanded ? '收起' : `更多(${ccList.length - 2})` }}
|
||||
</text>
|
||||
<text class="more-icon" :class="{ expanded: csrExpanded }">▼</text>
|
||||
</view>
|
||||
<view v-if="ccList.length === 0" class="empty-tip">
|
||||
<text>暂无抄送人,请添加</text>
|
||||
</view>
|
||||
@ -113,14 +85,10 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, onMounted } from "vue";
|
||||
import { getApproversByRuleId } from "@/api/base/jsQjApi";
|
||||
import { getByYwIdAndYwTypeApi } from "@/api/base/lcglSpApi";
|
||||
import { getSprAndCsrByRuleId, getByYwIdAndYwTypeApi } from "@/api/base/lcglSpApi";
|
||||
import { useCommonStore } from "@/store/modules/common";
|
||||
import BasicJsPicker from "@/components/BasicJsPicker/Picker.vue";
|
||||
|
||||
// 声明uni全局对象类型
|
||||
declare const uni: any;
|
||||
|
||||
// 定义教师信息接口(参照JsVo)
|
||||
interface JsInfo {
|
||||
id: string;
|
||||
@ -130,27 +98,43 @@ interface JsInfo {
|
||||
headPic?: string;
|
||||
userId?: number;
|
||||
deptId?: string;
|
||||
fixed?: boolean; // 固定
|
||||
}
|
||||
|
||||
// 数据转换公共接口
|
||||
const normalizeTeacherData = (item: any): JsInfo => {
|
||||
const normalizeTeacherData = (item: any, fixed: boolean): JsInfo => {
|
||||
return {
|
||||
id: item.id || item.value,
|
||||
jsxm: item.jsxm || item.label,
|
||||
id: item.userId || item.id || item.value,
|
||||
jsxm: item.userName || item.jsxm || item.label,
|
||||
lxdh: item.lxdh,
|
||||
sfzh: item.sfzh,
|
||||
headPic: item.headPic,
|
||||
userId: item.userId,
|
||||
deptId: item.deptId,
|
||||
fixed: fixed,
|
||||
};
|
||||
};
|
||||
|
||||
// 根据ID去重的函数
|
||||
const uniqueById = (array: any[]) => {
|
||||
return array.filter((item, index, self) =>
|
||||
index === self.findIndex(t => t.id === item.id)
|
||||
);
|
||||
};
|
||||
|
||||
// 根据userId去重的函数
|
||||
const uniqueByUserId = (array: any[]) => {
|
||||
return array.filter((item, index, self) =>
|
||||
index === self.findIndex(t => t.userId === item.userId)
|
||||
);
|
||||
};
|
||||
|
||||
// 接收外部传入属性并设置默认值
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
defaultValue?: any;
|
||||
ruleId?: string;
|
||||
qjId?: string; // 请假ID,用于重新提交时获取已有审批人
|
||||
ywId?: string; // 请假ID,用于重新提交时获取已有审批人
|
||||
}>(),
|
||||
{
|
||||
defaultValue: () => ({
|
||||
@ -158,7 +142,7 @@ const props = withDefaults(
|
||||
csrList: [],
|
||||
}),
|
||||
ruleId: "",
|
||||
qjId: "",
|
||||
ywId: "",
|
||||
}
|
||||
);
|
||||
|
||||
@ -169,6 +153,26 @@ const emit = defineEmits(["change"]);
|
||||
const approvers = ref<JsInfo[]>([]);
|
||||
const ccList = ref<JsInfo[]>([]);
|
||||
|
||||
// 配置数据
|
||||
const configSprList = ref<any>([]);
|
||||
const configCsrList = ref<any>([]);
|
||||
|
||||
// 抄送人展开状态
|
||||
const csrExpanded = ref(false);
|
||||
|
||||
// 计算属性:显示的抄送人列表
|
||||
const displayedCsrList = computed(() => {
|
||||
if (csrExpanded.value || ccList.value.length <= 2) {
|
||||
return ccList.value;
|
||||
}
|
||||
return ccList.value.slice(0, 2);
|
||||
});
|
||||
|
||||
// 切换抄送人展开状态
|
||||
const toggleCsrExpanded = () => {
|
||||
csrExpanded.value = !csrExpanded.value;
|
||||
};
|
||||
|
||||
// 教师选择器引用
|
||||
const approverPickerRef = ref();
|
||||
const ccPickerRef = ref();
|
||||
@ -176,66 +180,18 @@ const ccPickerRef = ref();
|
||||
// 获取common store
|
||||
const commonStore = useCommonStore();
|
||||
|
||||
// 初始化数据
|
||||
const initData = () => {
|
||||
if (props.defaultValue) {
|
||||
if (
|
||||
props.defaultValue.sprList &&
|
||||
Array.isArray(props.defaultValue.sprList)
|
||||
) {
|
||||
// 使用公共接口确保数据格式一致
|
||||
approvers.value = props.defaultValue.sprList.map(normalizeTeacherData);
|
||||
}
|
||||
if (
|
||||
props.defaultValue.csrList &&
|
||||
Array.isArray(props.defaultValue.csrList)
|
||||
) {
|
||||
// 使用公共接口确保数据格式一致
|
||||
ccList.value = props.defaultValue.csrList.map(normalizeTeacherData);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 监听外部数据变化(仅用于初始化)
|
||||
watch(
|
||||
() => props.defaultValue,
|
||||
() => {
|
||||
initData();
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
// 获取默认审批人和抄送人
|
||||
const loadDefaultApprovers = async () => {
|
||||
try {
|
||||
// 如果有请假ID,优先从LcglSp表获取已有审批人信息
|
||||
if (props.qjId) {
|
||||
await loadExistingApprovers();
|
||||
} else if (props.ruleId) {
|
||||
// 否则从LcglSet表获取默认配置
|
||||
await loadDefaultFromLcglSet();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取默认审批人失败:", error);
|
||||
uni.showToast({
|
||||
title: "获取默认审批人失败",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 从LcglSp表获取已有审批人信息(重新提交时使用)
|
||||
const loadExistingApprovers = async () => {
|
||||
try {
|
||||
const response = await getByYwIdAndYwTypeApi(props.qjId, "JS_QJ");
|
||||
const response = await getByYwIdAndYwTypeApi(props.ywId, "JS_QJ");
|
||||
if (
|
||||
response &&
|
||||
response.resultCode === 1 &&
|
||||
response.result &&
|
||||
Array.isArray(response.result)
|
||||
) {
|
||||
const spList = response.result;
|
||||
|
||||
let spList = response.result;
|
||||
|
||||
// 分离审批人和抄送人
|
||||
let approverList: any = [];
|
||||
let ccListData: any = [];
|
||||
@ -250,14 +206,27 @@ const loadExistingApprovers = async () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 根据userId去重
|
||||
approverList = uniqueByUserId(approverList);
|
||||
ccListData = uniqueByUserId(ccListData);
|
||||
|
||||
|
||||
let changeFlag = false;
|
||||
// 如果当前没有审批人或抄送人,则使用已有数据
|
||||
if (approvers.value.length === 0 && approverList.length > 0) {
|
||||
approvers.value = approverList.map(normalizeTeacherData);
|
||||
approvers.value = approverList.map((item:any) => {
|
||||
// 判断是否在config中
|
||||
const f = configSprList.value.filter((config:any) => config.userId === item.userId);
|
||||
return normalizeTeacherData(item, f && f.length > 0);
|
||||
});
|
||||
changeFlag = true;
|
||||
}
|
||||
if (ccList.value.length === 0 && ccListData.length > 0) {
|
||||
ccList.value = ccListData.map(normalizeTeacherData);
|
||||
ccList.value = ccListData.map((item:any) => {
|
||||
// 判断是否在config中
|
||||
const f = configCsrList.value.filter((config:any) => config.userId === item.userId);
|
||||
return normalizeTeacherData(item, f && f.length > 0);
|
||||
});
|
||||
changeFlag = true;
|
||||
}
|
||||
if (changeFlag) {
|
||||
@ -272,30 +241,11 @@ const loadExistingApprovers = async () => {
|
||||
// 从LcglSet表获取默认配置
|
||||
const loadDefaultFromLcglSet = async () => {
|
||||
try {
|
||||
const response = await getApproversByRuleId(props.ruleId);
|
||||
const response = await getSprAndCsrByRuleId(props.ruleId);
|
||||
if (response && response.resultCode === 1 && response.result) {
|
||||
const data = response.result;
|
||||
let changeFlag = false;
|
||||
// 如果当前没有审批人或抄送人,则使用默认值
|
||||
if (
|
||||
approvers.value.length === 0 &&
|
||||
data.approvers &&
|
||||
Array.isArray(data.approvers)
|
||||
) {
|
||||
approvers.value = data.approvers.map(normalizeTeacherData);
|
||||
changeFlag = true;
|
||||
}
|
||||
if (
|
||||
ccList.value.length === 0 &&
|
||||
data.ccList &&
|
||||
Array.isArray(data.ccList)
|
||||
) {
|
||||
ccList.value = data.ccList.map(normalizeTeacherData);
|
||||
changeFlag = true;
|
||||
}
|
||||
if (changeFlag) {
|
||||
notifyChange();
|
||||
}
|
||||
configSprList.value = data.sprList;
|
||||
configCsrList.value = data.csrList;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取默认审批人失败:", error);
|
||||
@ -336,8 +286,16 @@ const moveApproverDown = (index: number) => {
|
||||
const handleApproverChange = (selectedTeachers: any[]) => {
|
||||
if (Array.isArray(selectedTeachers)) {
|
||||
// 使用公共接口确保数据格式一致
|
||||
const normalizedTeachers = selectedTeachers.map(normalizeTeacherData);
|
||||
const normalizedTeachers = selectedTeachers.map((item:any) => {
|
||||
// 判断是否在config中
|
||||
const f = configSprList.value.filter((config:any) => config.userId === item.userId);
|
||||
return normalizeTeacherData(item, f && f.length > 0);
|
||||
});
|
||||
approvers.value.push(...normalizedTeachers);
|
||||
|
||||
// 根据ID去重
|
||||
approvers.value = uniqueById(approvers.value);
|
||||
|
||||
notifyChange();
|
||||
uni.showToast({
|
||||
title: "审批人设置成功",
|
||||
@ -350,8 +308,16 @@ const handleApproverChange = (selectedTeachers: any[]) => {
|
||||
const handleCcChange = (selectedTeachers: any[]) => {
|
||||
if (Array.isArray(selectedTeachers)) {
|
||||
// 使用公共接口确保数据格式一致
|
||||
const normalizedTeachers = selectedTeachers.map(normalizeTeacherData);
|
||||
const normalizedTeachers = selectedTeachers.map((item:any) => {
|
||||
// 判断是否在config中
|
||||
const f = configCsrList.value.filter((config:any) => config.userId === item.userId);
|
||||
return normalizeTeacherData(item, f && f.length > 0);
|
||||
});
|
||||
ccList.value.push(...normalizedTeachers);
|
||||
|
||||
// 根据ID去重
|
||||
ccList.value = uniqueById(ccList.value);
|
||||
|
||||
notifyChange();
|
||||
uni.showToast({
|
||||
title: "抄送人设置成功",
|
||||
@ -409,11 +375,19 @@ const getExcludeCcIds = () => {
|
||||
// 组件挂载时加载默认数据
|
||||
onMounted(async () => {
|
||||
try {
|
||||
initData();
|
||||
await loadDefaultApprovers();
|
||||
|
||||
// 预加载教师数据
|
||||
await commonStore.getAllJsBasicInfoVo();
|
||||
// 预加载审批人数据
|
||||
await loadDefaultFromLcglSet();
|
||||
// 判断数据
|
||||
if (!props.ywId) {
|
||||
approvers.value = configSprList.value.map((item:any) => normalizeTeacherData(item, true));
|
||||
ccList.value = configCsrList.value.map((item:any) => normalizeTeacherData(item, true));
|
||||
} else {
|
||||
loadExistingApprovers();
|
||||
}
|
||||
// 重新构建数据
|
||||
console.log("SprList组件初始化成功");
|
||||
} catch (error) {
|
||||
console.error("SprList组件初始化失败:", error);
|
||||
}
|
||||
@ -520,7 +494,43 @@ onMounted(async () => {
|
||||
border-radius: 12rpx;
|
||||
border: 2rpx dashed #dee2e6;
|
||||
}
|
||||
|
||||
.more-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16rpx 32rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: 40rpx;
|
||||
background: #f8f9fa;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 12rpx;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:active {
|
||||
background: #e9ecef;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.more-text {
|
||||
font-size: 28rpx;
|
||||
color: #007aff;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.more-icon {
|
||||
font-size: 24rpx;
|
||||
color: #007aff;
|
||||
transition: transform 0.3s ease;
|
||||
|
||||
&.expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@ -28,7 +28,7 @@
|
||||
</view>
|
||||
<!-- 审批人 -->
|
||||
<view class="info-section spr" v-if="sprSpList.length > 0">
|
||||
<view class="section-title">审批人</view>
|
||||
<view class="section-title">审批人({{ sprSpList.length || 0 }})</view>
|
||||
<view class="sp-list">
|
||||
<view v-for="spr in sprSpList" :key="spr.id" class="sp-item">
|
||||
<view class="sp-info">
|
||||
@ -54,14 +54,14 @@
|
||||
</view>
|
||||
<!-- 抄送人 -->
|
||||
<view class="info-section csr" v-if="csrSpList.length > 0">
|
||||
<view class="section-title">抄送人</view>
|
||||
<view class="section-title">抄送人({{ csrSpList.length || 0 }})</view>
|
||||
<view class="sp-list">
|
||||
<view v-for="csr in displayedcsrList" :key="csr.id" class="sp-item">
|
||||
<view v-for="csr in displayedCsrList" :key="csr.id" class="sp-item">
|
||||
<view class="sp-info">
|
||||
<text class="name">{{ csr.userName }}</text>
|
||||
<text class="dept">{{ csr.deptName }}</text>
|
||||
<text class="status" :class="getSprStatusClass(csr.approveStatus)">
|
||||
{{ getSprStatusText(csr.approveStatus) }}
|
||||
<text class="status" :class="getCsrStatusClass(csr.approveStatus)">
|
||||
{{ getCsrStatusText(csr.approveStatus) }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
@ -76,7 +76,7 @@
|
||||
</view>
|
||||
<!-- 操作记录 -->
|
||||
<view class="info-section log" v-if="logList.length > 0">
|
||||
<view class="section-title">操作记录</view>
|
||||
<view class="section-title">操作记录({{ logList.length || 0 }})</view>
|
||||
<view class="sp-list">
|
||||
<view v-for="log in displayedLogList" :key="log.id" class="sp-item">
|
||||
<view class="log-header">
|
||||
@ -153,7 +153,7 @@ const csrExpanded = ref(false);
|
||||
const logExpanded = ref(false);
|
||||
|
||||
// 计算属性:显示的抄送人列表
|
||||
const displayedcsrList = computed(() => {
|
||||
const displayedCsrList = computed(() => {
|
||||
if (csrExpanded.value || csrSpList.value.length <= 2) {
|
||||
return csrSpList.value;
|
||||
}
|
||||
@ -232,8 +232,11 @@ const getSprStatusText = (status: any) => {
|
||||
// 获取抄送人状态样式类
|
||||
const getCsrStatusClass = (status: any) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
pending: "status-pending",
|
||||
approved: "status-approved",
|
||||
unread: "status-unread",
|
||||
read: "status-read",
|
||||
cc_sent: "status-approved",
|
||||
};
|
||||
return statusMap[status] || "status-default";
|
||||
};
|
||||
@ -241,6 +244,9 @@ const getCsrStatusClass = (status: any) => {
|
||||
// 获取抄送人状态文本
|
||||
const getCsrStatusText = (status: any) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
pending: "待抄送",
|
||||
approved: "已抄送",
|
||||
cc_sent: "已抄送",
|
||||
unread: "未读",
|
||||
read: "已读",
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<!-- 原始审批人 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">原审批人</text>
|
||||
<text class="section-title">原审批人({{ srcSprList.length || 0 }})</text>
|
||||
</view>
|
||||
<view class="list-content">
|
||||
<view v-for="(spr, index) in srcSprList" :key="index" class="list-item readonly">
|
||||
@ -26,10 +26,10 @@
|
||||
<!-- 原始抄送人 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">原抄送人</text>
|
||||
<text class="section-title">原抄送人({{ srcCsrList.length || 0 }})</text>
|
||||
</view>
|
||||
<view class="list-content">
|
||||
<view v-for="(csr, index) in srcCsrList" :key="index" class="list-item readonly">
|
||||
<view v-for="(csr, index) in displayedSrcCsrList" :key="index" class="list-item readonly">
|
||||
<view class="item-info">
|
||||
<text class="item-name">{{ csr.jsxm }}</text>
|
||||
</view>
|
||||
@ -38,29 +38,29 @@
|
||||
<view v-if="srcCsrList.length === 0" class="empty-tip">
|
||||
<text>暂无原抄送人</text>
|
||||
</view>
|
||||
|
||||
<!-- 更多按钮 -->
|
||||
<view v-if="srcCsrList.length > 2" class="more-button" @click="toggleSrcCsrExpanded">
|
||||
<text class="more-text">
|
||||
{{ srcCsrExpanded ? '收起' : `更多(${srcCsrList.length - 2})` }}
|
||||
</text>
|
||||
<text class="more-icon" :class="{ expanded: srcCsrExpanded }">▼</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审批人列表 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">审批转办人</text>
|
||||
<text class="section-title">{{ newSprTitle }}</text>
|
||||
<!-- 审批人选择器 -->
|
||||
<BasicJsPicker
|
||||
ref="approverPickerRef"
|
||||
:customTrigger="true"
|
||||
:multiple="true"
|
||||
:excludeIds="getExcludeApproverIds()"
|
||||
:defaultValue="approvers"
|
||||
title="选择审批转办人"
|
||||
placeholder="请选择审批转办人"
|
||||
searchPlaceholder="搜索审批转办人"
|
||||
@change="handleApproverChange"
|
||||
>
|
||||
<BasicJsPicker ref="approverPickerRef" :customTrigger="true" :multiple="true"
|
||||
:excludeIds="getExcludeApproverIds()" :defaultValue="approvers" title="选择审批人" placeholder="请选择审批转办人"
|
||||
searchPlaceholder="搜索审批人" @change="handleApproverChange">
|
||||
<template #trigger>
|
||||
<view class="add-btn">
|
||||
<text class="add-icon">+</text>
|
||||
<text class="add-text">添加审批转办人</text>
|
||||
<text class="add-text">添加{{ newSprTitle }}</text>
|
||||
</view>
|
||||
</template>
|
||||
</BasicJsPicker>
|
||||
@ -73,33 +73,16 @@
|
||||
</view>
|
||||
<view class="item-actions">
|
||||
<!-- 上移箭头 -->
|
||||
<uni-icons
|
||||
v-if="index > 0"
|
||||
type="top"
|
||||
size="18"
|
||||
color="#666"
|
||||
@click="moveApproverUp(index)"
|
||||
class="action-icon"
|
||||
></uni-icons>
|
||||
|
||||
<uni-icons v-if="index > 0" type="top" size="18" color="#666" @click="moveApproverUp(index)"
|
||||
class="action-icon"></uni-icons>
|
||||
|
||||
<!-- 下移箭头 -->
|
||||
<uni-icons
|
||||
v-if="index < approvers.length - 1"
|
||||
type="bottom"
|
||||
size="18"
|
||||
color="#666"
|
||||
@click="moveApproverDown(index)"
|
||||
class="action-icon"
|
||||
></uni-icons>
|
||||
|
||||
<uni-icons v-if="index < approvers.length - 1" type="bottom" size="18" color="#666"
|
||||
@click="moveApproverDown(index)" class="action-icon"></uni-icons>
|
||||
|
||||
<!-- 删除图标改为垃圾桶图标 -->
|
||||
<uni-icons
|
||||
type="trash"
|
||||
size="18"
|
||||
color="#666"
|
||||
@click="removeApprover(index)"
|
||||
class="action-icon"
|
||||
></uni-icons>
|
||||
<uni-icons type="trash" size="18" color="#666" @click="removeApprover(index)"
|
||||
class="action-icon"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -112,23 +95,14 @@
|
||||
<!-- 抄送人列表 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">新增抄送人</text>
|
||||
<text class="section-title">{{ newCsrTitle }}</text>
|
||||
<!-- 抄送人选择器 -->
|
||||
<BasicJsPicker
|
||||
ref="ccPickerRef"
|
||||
:customTrigger="true"
|
||||
:multiple="true"
|
||||
:excludeIds="getExcludeCcIds()"
|
||||
:defaultValue="ccList"
|
||||
title="选择抄送人"
|
||||
placeholder="请选择抄送人"
|
||||
searchPlaceholder="搜索抄送人"
|
||||
@change="handleCcChange"
|
||||
>
|
||||
<BasicJsPicker ref="ccPickerRef" :customTrigger="true" :multiple="true" :excludeIds="getExcludeCcIds()"
|
||||
:defaultValue="ccList" title="选择抄送人" placeholder="请选择抄送人" searchPlaceholder="搜索抄送人" @change="handleCcChange">
|
||||
<template #trigger>
|
||||
<view class="add-btn">
|
||||
<text class="add-icon">+</text>
|
||||
<text class="add-text">添加抄送人</text>
|
||||
<text class="add-text">添加{{ newCsrTitle }}</text>
|
||||
</view>
|
||||
</template>
|
||||
</BasicJsPicker>
|
||||
@ -159,6 +133,15 @@ import { useDataStore } from "@/store/modules/data";
|
||||
import BasicJsPicker from "@/components/BasicJsPicker/Picker.vue";
|
||||
const { getLcgl } = useDataStore();
|
||||
|
||||
// 接收外部传入属性并设置默认值
|
||||
const props = withDefaults(defineProps<{
|
||||
newSprTitle?: string;
|
||||
newCsrTitle?: string;
|
||||
}>(), {
|
||||
newSprTitle: "审批转办人",
|
||||
newCsrTitle: "新抄送人"
|
||||
});
|
||||
|
||||
// 定义教师信息接口(参照JsVo)
|
||||
interface JsInfo {
|
||||
id: string;
|
||||
@ -207,6 +190,23 @@ const ccPickerRef = ref();
|
||||
// 获取common store
|
||||
const commonStore = useCommonStore();
|
||||
|
||||
// 抄送人展开状态
|
||||
const srcCsrExpanded = ref(false);
|
||||
|
||||
// 计算属性:显示的抄送人列表
|
||||
const displayedSrcCsrList = computed(() => {
|
||||
if (srcCsrExpanded.value || srcCsrList.value.length <= 2) {
|
||||
return srcCsrList.value;
|
||||
}
|
||||
return srcCsrList.value.slice(0, 2);
|
||||
});
|
||||
|
||||
// 切换抄送人展开状态
|
||||
const toggleSrcCsrExpanded = () => {
|
||||
srcCsrExpanded.value = !srcCsrExpanded.value;
|
||||
};
|
||||
|
||||
|
||||
// 获取审批人状态样式类
|
||||
const getSprStatusClass = (status: any) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
@ -238,19 +238,19 @@ const getSprStatusText = (status: any) => {
|
||||
const initData = (jsList: any) => {
|
||||
const srcSprSpList = getLcgl.sprSpList || [];
|
||||
const srcCsrSpList = getLcgl.csrSpList || [];
|
||||
|
||||
|
||||
// 处理原始审批人列表
|
||||
srcSprList.value = srcSprSpList.map((sp: any) => {
|
||||
const js = jsList.find((js: any) => js.userId === sp.userId);
|
||||
return js ? normalizeTeacherData(js, sp) : {};
|
||||
});
|
||||
|
||||
|
||||
// 处理原始抄送人列表
|
||||
srcCsrList.value = srcCsrSpList.map((sp: any) => {
|
||||
const js = jsList.find((js: any) => js.userId === sp.userId);
|
||||
return js ? normalizeTeacherData(js, sp) : {};
|
||||
});
|
||||
|
||||
|
||||
// 根据spList里面的数据的userId, 去查询对应的jsList匹配userId的数据
|
||||
approvers.value = [];
|
||||
ccList.value = [];
|
||||
@ -375,11 +375,11 @@ onMounted(async () => {
|
||||
}
|
||||
});
|
||||
|
||||
const getNewSprList = () => {
|
||||
const getNewSprList = () => {
|
||||
return approvers.value;
|
||||
};
|
||||
|
||||
const getNewCsrList = () => {
|
||||
const getNewCsrList = () => {
|
||||
return ccList.value;
|
||||
};
|
||||
|
||||
@ -494,22 +494,22 @@ defineExpose({
|
||||
background-color: #f9f9f9;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
|
||||
&.status-skipped {
|
||||
background-color: #f0f5ff;
|
||||
color: #2f54eb;
|
||||
}
|
||||
|
||||
|
||||
&.status-stop {
|
||||
background-color: #fff1f0;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
|
||||
&.status-transfer {
|
||||
background-color: #f9f0ff;
|
||||
color: #722ed1;
|
||||
}
|
||||
|
||||
|
||||
&.status-default {
|
||||
background-color: #fafafa;
|
||||
color: #595959;
|
||||
@ -521,11 +521,11 @@ defineExpose({
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
|
||||
|
||||
.action-icon {
|
||||
padding: 6rpx;
|
||||
border-radius: 4rpx;
|
||||
|
||||
|
||||
&:active {
|
||||
background-color: #eee;
|
||||
}
|
||||
@ -555,6 +555,42 @@ defineExpose({
|
||||
border-radius: 12rpx;
|
||||
border: 2rpx dashed #ebedf0;
|
||||
}
|
||||
|
||||
.more-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16rpx 32rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: 40rpx;
|
||||
background: #f8f9fa;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 12rpx;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:active {
|
||||
background: #e9ecef;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.more-text {
|
||||
font-size: 28rpx;
|
||||
color: #007aff;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.more-icon {
|
||||
font-size: 24rpx;
|
||||
color: #007aff;
|
||||
transition: transform 0.3s ease;
|
||||
|
||||
&.expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ onLoad(async (data: any) => {
|
||||
const xsQj = res.result || {};
|
||||
if (xsQj.spResult != "A" && getXxts && getXxts.dbZt === "A") {
|
||||
uni.reLaunch({ url: '/pages/base/xs/qj/detail' });
|
||||
// const flag = await XkTfPageUtils.updateXxts();
|
||||
const flag = await XkTfPageUtils.updateXxts();
|
||||
} else {
|
||||
nextTick(() => {
|
||||
setData(xsQj);
|
||||
|
||||
176
src/pages/components/XtDkJs/index.vue
Normal file
176
src/pages/components/XtDkJs/index.vue
Normal file
@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<u-popup :show="dlgFlag" mode="bottom" width="calc(100% - 60rpx)" :closeOnClickOverlay="false" @close="closeDlg"
|
||||
class="transfer-popup">
|
||||
<view class="popup-content">
|
||||
<view class="popup-header">
|
||||
<view class="popup-title">转办设置</view>
|
||||
</view>
|
||||
<view class="popup-body">
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">转办原因</text>
|
||||
</view>
|
||||
<view class="list-content">
|
||||
<u-input v-model="spRemark" type="textarea" placeholder="请填写转办原因" :autoHeight="true" maxlength="200"
|
||||
class="remark-input" />
|
||||
</view>
|
||||
</view>
|
||||
<TransferSpCsMgr ref="transferSpCsMgrRef" />
|
||||
</view>
|
||||
<view class="popup-actions flex-row justify-end mt-4">
|
||||
<u-button class="mr-2" @click="closeDlg">取消</u-button>
|
||||
<u-button type="primary" @click="submit">确定</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import TransferSpCsMgr from "@/components/TransferSpCsMgr/index.vue"
|
||||
|
||||
// 定义一个上级传入的emit响应事件用于接收数据变更
|
||||
const emit = defineEmits(["submit"]);
|
||||
|
||||
const transferSpCsMgrRef = ref<any>(null);
|
||||
const dlgFlag = ref(false);
|
||||
const spRemark = ref("");
|
||||
|
||||
const showDlg = (type: string) => {
|
||||
dlgFlag.value = true;
|
||||
};
|
||||
|
||||
const closeDlg = () => {
|
||||
dlgFlag.value = false;
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = () => {
|
||||
if (!spRemark.value || !spRemark.value.trim()) {
|
||||
uni.showToast({ title: "请填写转办原因", icon: "none" });
|
||||
return;
|
||||
}
|
||||
const newSprList = transferSpCsMgrRef.value.getNewSprList();
|
||||
const newCsrList = transferSpCsMgrRef.value.getNewCsrList();
|
||||
if (!newSprList.length) {
|
||||
uni.showToast({ title: "请选择审批转办人", icon: "none" });
|
||||
return;
|
||||
}
|
||||
emit('submit', { newSprList, newCsrList, spRemark: spRemark.value });
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
showDlg,
|
||||
closeDlg
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.transfer-popup {
|
||||
width: calc(100% - 60rpx);
|
||||
max-height: 90vh;
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 90vh;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
flex-shrink: 0;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #ebedf0;
|
||||
|
||||
.popup-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 30rpx;
|
||||
max-height: calc(90vh - 200rpx);
|
||||
|
||||
.flex-row {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #262626;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.remark-input {
|
||||
display: flex;
|
||||
align-items: flex-start; /* 垂直上对齐 */
|
||||
justify-content: flex-start; /* 水平居左对齐 */
|
||||
input {
|
||||
height: 160rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.popup-actions {
|
||||
flex-shrink: 0;
|
||||
padding: 30rpx;
|
||||
border-top: 1rpx solid #ebedf0;
|
||||
}
|
||||
|
||||
.transfer-form {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
|
||||
.list-content {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-actions {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
padding: 15px;
|
||||
border-top: 1px solid #eee;
|
||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.bottom-actions .u-button {
|
||||
flex: 1;
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
@ -7,6 +7,9 @@
|
||||
<view class="flex-row items-center pb-5">
|
||||
<u-button text="终止" class="ml-15 mr-7" :plain="true" @click="showDlg('stop')" />
|
||||
<u-button text="转办" class="mr-15 mr-7" :plain="true" @click="showTransfer" />
|
||||
</view>
|
||||
<view class="flex-row items-center pb-5">
|
||||
<u-button text="协调代课教师" class="mr-15 mr-7" :plain="true" @click="showXtDlg" />
|
||||
</view>
|
||||
<!-- 驳回弹窗 -->
|
||||
<u-popup :show="dlgFlag" mode="center" :closeOnClickOverlay="false" @close="closeDlg">
|
||||
@ -24,12 +27,13 @@
|
||||
</view>
|
||||
</u-popup>
|
||||
<YwTransfer ref="transferRef" @submit="handleTransfer" />
|
||||
<XtDkJs ref="xtDkJsRef" @submit="handleXtDkJs" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import YwTransfer from "../YwTransfer/index.vue";
|
||||
|
||||
import XtDkJs from "../XtDkJs/index.vue";
|
||||
|
||||
// 接收外部传入属性并设置默认值
|
||||
const props = withDefaults(defineProps<{
|
||||
@ -43,6 +47,7 @@ const props = withDefaults(defineProps<{
|
||||
rejectValue?: string, // 默认的拒绝时的状态值
|
||||
approvedRemark?: string //
|
||||
autoToMessage?: boolean // 默认自动跳转到待办页面
|
||||
showXt?: boolean
|
||||
}>(), {
|
||||
spApi: async (params: any) => {},
|
||||
transferApi: async (params: any) => {},
|
||||
@ -53,13 +58,15 @@ const props = withDefaults(defineProps<{
|
||||
approvedValue: 'approved',
|
||||
rejectValue: 'rejected',
|
||||
approvedRemark: '同意',
|
||||
autoToMessage: true
|
||||
autoToMessage: true,
|
||||
showXt: false
|
||||
});
|
||||
|
||||
// 定义一个上级传入的emit响应事件用于接收数据变更
|
||||
const emit = defineEmits(['submit', 'reject', 'stop', 'transfer'])
|
||||
|
||||
const transferRef = ref<any>(null);
|
||||
const xtDkJsRef = ref<any>(null);
|
||||
|
||||
const dlgFlag = ref(false);
|
||||
const dlgType = ref("");
|
||||
@ -90,6 +97,10 @@ const showTransfer = () => {
|
||||
transferRef.value.showDlg();
|
||||
};
|
||||
|
||||
const showXtDlg = () => {
|
||||
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
const params = {
|
||||
...props.params
|
||||
@ -142,6 +153,26 @@ const handleTransfer = async (data: any) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 转办处理
|
||||
const handleXtDkJs = async (data: any) => {
|
||||
const params = {
|
||||
...props.params
|
||||
};
|
||||
const newSprList = data.newSprList || [];
|
||||
const newCsrList = data.newCsrList || [];
|
||||
params.spRemark = data.spRemark;
|
||||
params.zbrIds = newSprList.map((item: any) => item.userId).join(",");
|
||||
params.csrIds = newCsrList.map((item: any) => item.userId).join(",");
|
||||
uni.showLoading({ title: "正在转办..." });
|
||||
await props.transferApi(params);
|
||||
transferRef.value.closeDlg();
|
||||
uni.hideLoading();
|
||||
emit('transfer');
|
||||
if (props.autoToMessage) {
|
||||
goToMessage();
|
||||
}
|
||||
};
|
||||
|
||||
const handleDlgSubmit = async () => {
|
||||
if (!spRemark.value || !spRemark.value.trim()) {
|
||||
uni.showToast({ title: "请填写" + dlgTips.value, icon: "none" });
|
||||
|
||||
@ -19,10 +19,10 @@
|
||||
<text class="label">代课老师:</text>
|
||||
<view class="value">{{ item.jsName }}</view>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<!-- <view class="info-row">
|
||||
<text class="label">确认状态:</text>
|
||||
<view class="value">{{ item.statusLabel }}</view>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -72,6 +72,10 @@ watch(
|
||||
);
|
||||
|
||||
const init = async () => {
|
||||
if (!props.qjId) {
|
||||
console.log("初始化的qjId为空");
|
||||
return;
|
||||
}
|
||||
const res = await findQjById({ id: props.qjId });
|
||||
qjData.value = (res && res.result) ? res.result : {};
|
||||
if (props.dbFlag) {
|
||||
|
||||
@ -102,10 +102,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getPkkbByJsRangeTimeApi } from "@/api/base/jsQjApi";
|
||||
import { getPkkbByJsRangeTimeApi, findDkPageApi } from "@/api/base/jsQjApi";
|
||||
import BasicJsPicker from "@/components/BasicJsPicker/Picker.vue";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useCommonStore } from "@/store/modules/common";
|
||||
const { getJs } = useUserStore();
|
||||
const { getAllJsBasicInfoVo } = useCommonStore();
|
||||
|
||||
// 接收外部传入属性
|
||||
const props = withDefaults(
|
||||
@ -114,6 +116,7 @@ const props = withDefaults(
|
||||
}>(),
|
||||
{
|
||||
data: () => ({
|
||||
qjId: "",
|
||||
jsId: "",
|
||||
qjkstime: "", // 请假开始时间
|
||||
qjjstime: "", // 请假结束时间
|
||||
@ -165,6 +168,10 @@ const switchTab = (index: number) => {
|
||||
};
|
||||
|
||||
const getPkkbList = async () => {
|
||||
// 判断时间是否合法
|
||||
if (!props.data.qjjstime || !props.data.qjkstime) {
|
||||
return;
|
||||
}
|
||||
const res = await getPkkbByJsRangeTimeApi({
|
||||
jsId: props.data.jsId,
|
||||
startTime: props.data.qjkstime,
|
||||
@ -177,6 +184,7 @@ const getPkkbList = async () => {
|
||||
srcData[key] = {
|
||||
dkJsId: item.dkJsId,
|
||||
dkJsName: item.dkJsName,
|
||||
userId: item.userId
|
||||
};
|
||||
});
|
||||
const kmMap: any = {};
|
||||
@ -189,13 +197,14 @@ const getPkkbList = async () => {
|
||||
if (src) {
|
||||
item.dkJsId = src.dkJsId;
|
||||
item.dkJsName = src.dkJsName;
|
||||
item.userId = src.userId;
|
||||
} else {
|
||||
item.dkJsId = "";
|
||||
item.dkJsName = "";
|
||||
item.userId = "";
|
||||
}
|
||||
kmMap[item.pkId] = kmMap[item.pkId] || {
|
||||
kmMap[item.pkMc] = kmMap[item.pkMc] || {
|
||||
pkMc: item.pkMc,
|
||||
pkId: item.pkId,
|
||||
};
|
||||
return item;
|
||||
});
|
||||
@ -206,11 +215,13 @@ const getPkkbList = async () => {
|
||||
const changeJsByTy = (selected: any, item: any) => {
|
||||
item.dkJsId = selected.value;
|
||||
item.dkJsName = selected.label;
|
||||
item.userId = selected.userId;
|
||||
const newList = dkList.value.map((dk: any) => {
|
||||
return {
|
||||
...dk,
|
||||
dkJsId: item.dkJsId,
|
||||
dkJsName: item.dkJsName,
|
||||
userId: item.userId
|
||||
};
|
||||
});
|
||||
dkList.value = newList;
|
||||
@ -227,10 +238,11 @@ const changeJsByTy = (selected: any, item: any) => {
|
||||
const changeJsByKm = (selected: any, item: any) => {
|
||||
item.dkJsId = selected.value;
|
||||
item.dkJsName = selected.label;
|
||||
item.userId = selected.userId;
|
||||
// 同时更新主列表中的数据
|
||||
const newList = dkList.value.map((dk: any) => {
|
||||
if (dk.pkId === item.pkId) {
|
||||
return { ...dk, dkJsId: item.dkJsId, dkJsName: item.dkJsName };
|
||||
if (dk.pkMc === item.pkMc) {
|
||||
return { ...dk, dkJsId: item.dkJsId, dkJsName: item.dkJsName, userId: item.userId };
|
||||
}
|
||||
return dk;
|
||||
});
|
||||
@ -240,6 +252,7 @@ const changeJsByKm = (selected: any, item: any) => {
|
||||
const changeJs = (selected: any, item: any) => {
|
||||
item.dkJsId = selected.value;
|
||||
item.dkJsName = selected.label;
|
||||
item.userId = selected.userId;
|
||||
};
|
||||
|
||||
const validate = async () => {
|
||||
@ -262,6 +275,38 @@ const validate = async () => {
|
||||
return true;
|
||||
};
|
||||
|
||||
const initDkList = async () => {
|
||||
const resJs = await getAllJsBasicInfoVo();
|
||||
const jsList = resJs.result || [];
|
||||
|
||||
const res: any = await findDkPageApi({
|
||||
qjId: props.data.qjId,
|
||||
page: 1,
|
||||
rows: 1000,
|
||||
});
|
||||
const kmMap: any = {};
|
||||
const rows = (res && (res.rows || res.result || res.data)) || [];
|
||||
dkList.value = rows.map((item: any) => {
|
||||
item.dktime = item.dktime.split(" ")[0];
|
||||
item.jcmc = jsTypeMc[item.jcType] + "第" + item.jc + "节";
|
||||
const xq: number = item.xq - 1;
|
||||
item.xqLabel = wdNameList.value[xq];
|
||||
const js = jsList.find((js: any) => js.id === item.jsId);
|
||||
if (js) {
|
||||
item.dkJsId = js.id;
|
||||
item.dkJsName = js.jsxm;
|
||||
item.userId = js.userId;
|
||||
}
|
||||
kmMap[item.pkMc] = kmMap[item.pkMc] || {
|
||||
pkMc: item.pkMc,
|
||||
};
|
||||
return item;
|
||||
});
|
||||
// 将kmMap转换成value对应的数组
|
||||
kmDkList.value = Object.values(kmMap);
|
||||
};
|
||||
|
||||
|
||||
// 暴露接口给ref调用
|
||||
const getDkList = () => {
|
||||
return dkList.value;
|
||||
@ -272,6 +317,7 @@ defineExpose({
|
||||
getPkkbList,
|
||||
validate,
|
||||
getDkList,
|
||||
initDkList,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -7,9 +7,8 @@
|
||||
</template>
|
||||
<template #spcs>
|
||||
<BasicSpCsMgr
|
||||
ruleId="yfzc_js_qj"
|
||||
:qjId="formData.id"
|
||||
:defaultValue="defSpCs"
|
||||
rule-id="yfzc_js_qj"
|
||||
:yw-id="formData.id"
|
||||
@change="onSpCsChange"
|
||||
/>
|
||||
</template>
|
||||
@ -18,7 +17,7 @@
|
||||
<template #bottom>
|
||||
<view class="white-bg-color py-5">
|
||||
<view class="flex-row items-center pb-10 pt-5">
|
||||
<u-button text="取消" class="ml-15 mr-7" :plain="true" @click="navigateBack" />
|
||||
<u-button text="取消" class="ml-15 mr-7" :plain="true" @click="goBack" />
|
||||
<u-button text="提交" class="mr-15 mr-7" type="primary" @click="submit" />
|
||||
</view>
|
||||
</view>
|
||||
@ -29,7 +28,6 @@
|
||||
<script setup lang="ts">
|
||||
import JsQjDkEdit from "./jsQjDkEdit.vue"
|
||||
import BasicSpCsMgr from "@/components/BasicSpCsMgr/index.vue"
|
||||
import { navigateBack } from "@/utils/uniapp";
|
||||
import { useForm } from "@/components/BasicForm/hooks/useForm";
|
||||
import { jsQjSqApi, jsQjCxtjApi } from "@/api/base/jsQjApi";
|
||||
import { showToast } from "@/utils/uniapp";
|
||||
@ -62,14 +60,6 @@ let formData = ref<any>({
|
||||
jsId: getJs.id,
|
||||
});
|
||||
|
||||
const defSpCs = computed(() => {
|
||||
return {
|
||||
sprList: formData.value.sprList,
|
||||
csrList: formData.value.csrList,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const dkRef = ref<any>(null);
|
||||
|
||||
if (typeof props.data.dkfs === "string") {
|
||||
@ -206,9 +196,13 @@ const updateDk = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化
|
||||
setValue(props.data)
|
||||
updateDk();
|
||||
const initDk = () => {
|
||||
nextTick(() => {
|
||||
if (dkRef.value) {
|
||||
dkRef.value.initDkList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const submit = async () => {
|
||||
const fd = await getValue();
|
||||
@ -216,9 +210,6 @@ const submit = async () => {
|
||||
return;
|
||||
}
|
||||
const params = { ...fd };
|
||||
// 注入审批人/抄送人
|
||||
params.sprList = formData.value.sprList || [];
|
||||
params.csrList = formData.value.csrList || [];
|
||||
if (fd.dkfs === 0) {
|
||||
const dkList = dkRef.value.getDkList();
|
||||
if (!dkList.length) {
|
||||
@ -243,10 +234,15 @@ const submit = async () => {
|
||||
params.dkList = [];
|
||||
}
|
||||
}
|
||||
// 注入审批人/抄送人
|
||||
params.sprList = formData.value.sprList || [];
|
||||
params.csrList = formData.value.csrList || [];
|
||||
let submitApi = jsQjSqApi;
|
||||
if (props.data && props.data.id) {
|
||||
params.id = props.data.id;
|
||||
submitApi = jsQjCxtjApi
|
||||
params.id = props.data.id;
|
||||
params.jsId = getJs.id;
|
||||
params.jsName = getJs.jsxm;
|
||||
} else {
|
||||
params.id = null;
|
||||
params.jsId = getJs.id;
|
||||
@ -270,6 +266,23 @@ const onSpCsChange = (payload: any) => {
|
||||
formData.value.csrList = Array.isArray(payload.csrList) ? payload.csrList : [];
|
||||
}
|
||||
};
|
||||
|
||||
const goBack = () => {
|
||||
if (props.data && props.data.id) {
|
||||
uni.reLaunch({ url: "/pages/base/message/index" });
|
||||
} else {
|
||||
uni.reLaunch({ url: "/pages/base/service/index" });
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (props.data && props.data.id) {
|
||||
// 初始化
|
||||
setValue(props.data);
|
||||
initDk();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -53,7 +53,10 @@ const [register, { reload }] = useLayout({
|
||||
|
||||
// 查看详情或新增处理函数
|
||||
const goToDetail = (item: any | null) => {
|
||||
setData(item);
|
||||
setData({
|
||||
...item,
|
||||
from: 'list'
|
||||
});
|
||||
let url = '/pages/view/hr/jsQj/detail'; // 使用新路径
|
||||
uni.navigateTo({ url });
|
||||
};
|
||||
|
||||
@ -1,76 +1,117 @@
|
||||
<template>
|
||||
<BasicLayout>
|
||||
<view class="p-15">
|
||||
<view class="info-card">
|
||||
<view class="card-header">
|
||||
<text class="card-title">重新提交请假申请</text>
|
||||
</view>
|
||||
<view class="card-content">
|
||||
<text class="info-text">您的请假申请已被驳回,请修改后重新提交。</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="leave-page">
|
||||
<!-- 选项卡 -->
|
||||
<BasicTabs
|
||||
class="leave-tabs"
|
||||
ref="tabsRef"
|
||||
:list="tabList"
|
||||
bar-width="60px"
|
||||
scroll-count="4"
|
||||
:current="curTabIndex"
|
||||
@change="switchTab"
|
||||
/>
|
||||
|
||||
<view class="leave-edit" v-if="curTabIndex === 0">
|
||||
<!-- 使用请假申请组件 -->
|
||||
<JsQjEdit :data="qjData" />
|
||||
<JsQjEdit :data="qjData" v-if="qjData && qjData.id" />
|
||||
</view>
|
||||
</BasicLayout>
|
||||
|
||||
<view class="leave-list" v-else>
|
||||
<view class="mt-15">
|
||||
<LcglSp :yw-id="qjId" yw-type="JS_QJ" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { findQjById } from "@/api/base/jsQjApi";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { ref } from "vue";
|
||||
import JsQjEdit from "./components/jsQjEdit.vue";
|
||||
import LcglSp from "@/components/LcglSp/index.vue";
|
||||
import JsQjEdit from "./components/jsQjEdit.vue"
|
||||
import { QjPageUtils } from "@/utils/qjPageUtils";
|
||||
import { findQjById } from "@/api/base/jsQjApi";
|
||||
|
||||
const qjId = ref<string>();
|
||||
const { getJs } = useUserStore();
|
||||
const { getData, getXxts } = useDataStore();
|
||||
|
||||
// 响应式数据
|
||||
const tabList = ref([
|
||||
{ name: "重新提交", id: "leave-edit" },
|
||||
{ name: "审批流程", id: "leave-detail" },
|
||||
])
|
||||
|
||||
const curTabIndex = ref(0)
|
||||
|
||||
// 切换标签页
|
||||
const switchTab = (index: number) => {
|
||||
curTabIndex.value = index
|
||||
}
|
||||
|
||||
const dbFlag = ref(false);
|
||||
const qjId = ref('');
|
||||
const qjData = ref<any>({});
|
||||
|
||||
// 加载请假信息
|
||||
const loadQjData = async () => {
|
||||
try {
|
||||
const result:any = await findQjById({ id: qjId.value });
|
||||
if (result.code === 1) {
|
||||
qjData.value = result.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取请假信息失败:', error);
|
||||
}
|
||||
const spParams = computed(() => {
|
||||
return {
|
||||
xxtsId: getXxts.id,
|
||||
ywId: qjId.value
|
||||
};
|
||||
});
|
||||
|
||||
const loadData = async () => {
|
||||
const res = await findQjById({ id: qjId.value });
|
||||
qjData.value = (res && res.result) ? res.result : {};
|
||||
qjData.value.dkfs = parseInt(qjData.value.dkfs);
|
||||
};
|
||||
|
||||
onLoad((options:any) => {
|
||||
if (options.qjId) {
|
||||
qjId.value = options.qjId;
|
||||
loadQjData();
|
||||
onLoad(async (data?: any) => {
|
||||
const ret = await QjPageUtils.init(data);
|
||||
if (!ret || !ret.success) {
|
||||
return;
|
||||
}
|
||||
qjId.value = ret.qjId;
|
||||
dbFlag.value = ret.dbFlag;
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.info-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
.leave-page {
|
||||
flex: 1 0 1px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
.leave-tabs {
|
||||
flex: 0 0 45px;
|
||||
background: #fff;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 15px;
|
||||
|
||||
.info-text {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
.leave-edit,
|
||||
.leave-list {
|
||||
flex: 1 0 1px;
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.leave-edit {
|
||||
background: #fff;
|
||||
margin: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.leave-list {
|
||||
background: #fff;
|
||||
margin: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,41 +1,22 @@
|
||||
<template>
|
||||
<BasicLayout>
|
||||
<template #top>
|
||||
<view>
|
||||
<BasicTabs
|
||||
class="detail-tabs"
|
||||
:list="tabList"
|
||||
bar-width="60px"
|
||||
scroll-count="4"
|
||||
:current="curTabIndex"
|
||||
@change="switchTab"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<view class="qj-detail">
|
||||
<!-- 请假信息 -->
|
||||
<view v-show="curTabIndex === 0">
|
||||
<JsQjDetailInfo
|
||||
:qjId="qjId"
|
||||
:dbFlag="dbFlag"
|
||||
@loadQjData="handleQjDataLoaded"
|
||||
/>
|
||||
<view>
|
||||
<JsQjDetailInfo :qjId="qjId" :dbFlag="dbFlag" @loadQjData="handleQjDataLoaded" />
|
||||
</view>
|
||||
|
||||
<!-- 代课信息 -->
|
||||
<view v-show="curTabIndex === 1">
|
||||
<view>
|
||||
<view v-if="!showDkFlag" class="empty-dk">
|
||||
<view>{{ showDkEmptyLabel }}</view>
|
||||
</view>
|
||||
<JsQjDetailDk v-else
|
||||
:qjId="qjId"
|
||||
@loadDkList="handleDkListLoaded"
|
||||
/>
|
||||
<JsQjDetailDk v-else :qjId="qjId" @loadDkList="handleDkListLoaded" />
|
||||
</view>
|
||||
|
||||
<!-- 审批流程 -->
|
||||
<view v-show="curTabIndex === 2">
|
||||
<LcglSpList :yw-id="qjId" yw-type="JS_QJ" />
|
||||
<view class="mt-15">
|
||||
<LcglSp :yw-id="qjId" yw-type="JS_QJ" />
|
||||
</view>
|
||||
</view>
|
||||
<template #bottom>
|
||||
@ -53,34 +34,27 @@ import { useDataStore } from "@/store/modules/data";
|
||||
import { ref, computed } from "vue";
|
||||
import JsQjDetailInfo from "./components/jsQjDetailInfo.vue";
|
||||
import JsQjDetailDk from "./components/jsQjDetailDk.vue";
|
||||
import LcglSpList from "@/components/LcglSpList/index.vue";
|
||||
import LcglSp from "@/components/LcglSp/index.vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { QjPageUtils } from "@/utils/qjPageUtils";
|
||||
import { xxtsFindByIdApi } from "@/api/base/xxtsApi";
|
||||
|
||||
const { getData, setData } = useDataStore();
|
||||
|
||||
const tabList = ref<any>([
|
||||
{ name: "请假信息", id: "tab-qj" },
|
||||
{ name: "代课信息", id: "tab-dk" },
|
||||
{ name: "审批流程", id: "tab-sp" }
|
||||
]);
|
||||
const curTabIndex = ref(0);
|
||||
const { getData, setData, getXxts } = useDataStore();
|
||||
|
||||
const dbFlag = ref(false);
|
||||
const qjId = computed(() => getData.id);
|
||||
const qjId = ref('');
|
||||
const showDkFlag = ref(false);
|
||||
const showDkEmptyLabel = ref('');
|
||||
|
||||
|
||||
// 切换Tab
|
||||
const switchTab = (index: number) => {
|
||||
curTabIndex.value = index;
|
||||
};
|
||||
|
||||
const handleQjDataLoaded = (data: any) => {
|
||||
setData(data);
|
||||
data = data || {};
|
||||
const dkfs = typeof(data.dkfs) === "string" ? parseInt(data.dkfs) : (data.dkfs || 2);
|
||||
const bpmStatus = typeof(data.bpmStatus) === "string" ? parseInt(data.bpmStatus) : (data.bpmStatus || 1);
|
||||
showDkFlag.value = dkfs === 0 || (dkfs === 1 && bpmStatus > 4);
|
||||
if (data.spResult != "A" && getXxts && getXxts.dbZt === "A") {
|
||||
QjPageUtils.updateXxts();
|
||||
}
|
||||
setData(data);
|
||||
const dkfs = typeof (data.dkfs) === "string" ? parseInt(data.dkfs) : (data.dkfs || 2);
|
||||
const bpmStatus = typeof (data.bpmStatus) === "string" ? parseInt(data.bpmStatus) : (data.bpmStatus || 1);
|
||||
showDkFlag.value = dkfs === 0 || (dkfs === 1 && bpmStatus > 4);
|
||||
if (dkfs === 1) {
|
||||
showDkEmptyLabel.value = "等待教科处协调";
|
||||
} else if (dkfs === 2) {
|
||||
@ -93,11 +67,31 @@ const handleDkListLoaded = (list: any[]) => {
|
||||
};
|
||||
|
||||
const goHome = () => {
|
||||
setData({});
|
||||
uni.reLaunch({
|
||||
url: '/pages/base/service/index',
|
||||
});
|
||||
};
|
||||
|
||||
onLoad(async (data) => {
|
||||
if (getData && getData.id && (
|
||||
getData.from === "xxts-B" || getData.from === "list"
|
||||
)) {
|
||||
qjId.value = getData.id;
|
||||
// 从列表推送过来和消息推送过来的,跳过其他处理
|
||||
return;
|
||||
}
|
||||
const ret = await QjPageUtils.init({
|
||||
...data,
|
||||
detailFlag: true,
|
||||
});
|
||||
if (!ret || !ret.success) {
|
||||
return;
|
||||
}
|
||||
dbFlag.value = ret.dbFlag;
|
||||
qjId.value = ret.qjId;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -43,12 +43,6 @@ import { QjPageUtils } from "@/utils/qjPageUtils";
|
||||
const { getJs } = useUserStore();
|
||||
const { setData, getXxts } = useDataStore();
|
||||
|
||||
const tabList = ref<any>([
|
||||
{ name: "请假信息", id: "tab-qj" },
|
||||
{ name: "代课信息", id: "tab-dk" },
|
||||
{ name: "审批流程", id: "tab-sp" }
|
||||
]);
|
||||
const curTabIndex = ref(0);
|
||||
|
||||
const dbFlag = ref(false);
|
||||
const qjId = ref('');
|
||||
@ -62,14 +56,12 @@ const spParams = computed(() => {
|
||||
};
|
||||
});
|
||||
|
||||
// 切换Tab
|
||||
const switchTab = (index: number) => {
|
||||
curTabIndex.value = index;
|
||||
};
|
||||
|
||||
const handleQjDataLoaded = (data: any) => {
|
||||
setData(data);
|
||||
data = data || {};
|
||||
setData(data);
|
||||
if (data.spResult != "A" && getXxts && getXxts.dbZt === "A") {
|
||||
uni.reLaunch({ url: '/pages/base/xs/qj/detail' });
|
||||
}
|
||||
const dkfs = typeof(data.dkfs) === "string" ? parseInt(data.dkfs) : (data.dkfs || 2);
|
||||
showDkFlag.value = dkfs === 0;
|
||||
if (dkfs === 1) {
|
||||
|
||||
@ -31,15 +31,19 @@ export const QjPageUtils = {
|
||||
const xxtsRes = await xxtsFindByIdApi({ id: data.id });
|
||||
if (xxtsRes && xxtsRes.result) {
|
||||
const xxts = xxtsRes.result;
|
||||
setXxts(xxts);
|
||||
ret.qjId = xxts.xxzbId;
|
||||
// 检查待办状态
|
||||
if (xxts.dbZt === "B") {
|
||||
setData({ id: xxts.xxzbId });
|
||||
url = "/pages/view/hr/jsQj/detail";
|
||||
uni.reLaunch({ url });
|
||||
ret.success = false;
|
||||
} else {
|
||||
setXxts(xxts);
|
||||
ret.qjId = xxts.xxzbId;
|
||||
// 消息推送状态为B:
|
||||
setData({ id: xxts.xxzbId, from: "xxts-B" });
|
||||
if (!data.detailFlag) {
|
||||
url = "/pages/view/hr/jsQj/detail";
|
||||
uni.reLaunch({ url });
|
||||
ret.success = false;
|
||||
} else {
|
||||
ret.success = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
@ -68,6 +72,7 @@ export const QjPageUtils = {
|
||||
if (!getXxts || !getXxts.id) {
|
||||
return false;
|
||||
}
|
||||
console.log("更新待办状态:getXxts", getXxts);
|
||||
// 更新待办状态
|
||||
await xxtsSaveApi({
|
||||
id: getXxts.id,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user