公文流转

This commit is contained in:
hebo 2025-08-27 22:25:20 +08:00
parent 8fe418f37e
commit d99726d270
6 changed files with 814 additions and 549 deletions

View File

@ -144,3 +144,10 @@ export function saveChangesApi(params: any) {
export function getGwFlowByIdApi(id: string) {
return get(`/api/gw/getGwFlowById?id=${id}`);
}
/**
*
*/
export function gwTransferApi(params: any) {
return post('/api/gw/transfer', params);
}

View File

@ -206,6 +206,13 @@
"enablePullDownRefresh": false
}
},
{
"path": "pages/view/routine/gwlz/gwTransfer",
"style": {
"navigationBarTitleText": "公文转办",
"enablePullDownRefresh": false
}
},
{
"path": "pages/view/routine/JiFenPingJia/JiFenPingJia",
"style": {

View File

@ -21,13 +21,13 @@
<view class="teacher-details">
<view class="teacher-name">{{ teacherData.name }}</view>
<view class="teacher-position">{{ teacherData.position }}</view>
<view class="teacher-position">{{ teacherPosition }}</view>
<view class="teacher-class">{{ teacherData.className }}</view>
</view>
</view>
<!-- 统计信息 -->
<view class="stats-info">
<!-- 统计信息 - 暂时隐藏 -->
<!-- <view class="stats-info">
<view class="stat-item">
<text class="stat-label">积分</text>
<text class="stat-value">{{ teacherData.score }}</text>
@ -37,7 +37,7 @@
<text class="stat-label">工作量</text>
<text class="stat-value">{{ teacherData.workload }}课时</text>
</view>
</view>
</view> -->
<!-- 介绍文字 -->
<view class="teacher-intro">
@ -123,6 +123,7 @@
<script lang="ts" setup>
import { useUserStore } from "@/store/modules/user";
import { useCommonStore } from "@/store/modules/common";
import { imagUrl } from "@/utils";
import { reactive, ref, computed, onMounted } from "vue";
@ -157,19 +158,32 @@ interface DateItem {
date: string;
}
const { logout, getUser } = useUserStore();
const { logout, getUser, getJs } = useUserStore();
const { getZwListByLx } = useCommonStore();
//
const dzZwLabel = ref<string>("");
const qtZwLabel = ref<string>("");
//
const teacherData = reactive<TeacherData>({
name: getUser.loginName,
position: "教研组长",
className: "2014级1班班主任",
score: 48,
workload: 20,
introduction: "北冥有鱼,其名为鲲。鲲之大,不知其几千里也。",
name: getJs.jsxm || getUser.loginName,
position: "", //
className: getJs.njz || "",
score: 88, //
workload: 40, //
introduction: getJs.introduction || "北冥有鱼,其名为鲲。鲲之大,不知其几千里也。",
avatar: imagUrl(getUser.profilePhoto),
});
//
const teacherPosition = computed(() => {
const positions = [];
if (dzZwLabel.value) positions.push(dzZwLabel.value);
if (qtZwLabel.value) positions.push(qtZwLabel.value);
return positions.join('、') || '暂无职务信息';
});
// 退
const handleLogout = () => {
uni.showModal({
@ -192,7 +206,7 @@ const selectedDateIndex = ref(0); // 默认选中第一天
//
const weekDates = ref<DateItem[]>([]);
//
//
const generateScheduleData = () => {
const today = new Date();
const currentDay = today.getDay();
@ -202,269 +216,14 @@ const generateScheduleData = () => {
const data: Record<string, ScheduleItem[]> = {};
//
for (let i = 0; i < 7; i++) {
const date = new Date(startOfWeek);
date.setDate(startOfWeek.getDate() + i);
const dateStr = date.getDate().toString();
//
switch (i) {
case 0: //
data[dateStr] = [
{
startTime: '08:30',
endTime: '10:00',
title: '语文课',
type: 'class',
tag: '课程',
location: '教学楼A201',
description: '高一(3)班语文课',
details: true
},
{
startTime: '14:00',
endTime: '15:30',
title: '班主任会议',
type: 'meeting',
tag: '会议',
location: '会议室B302',
description: '讨论期中考试安排',
details: true
}
];
break;
case 1: //
data[dateStr] = [
{
startTime: '09:00',
endTime: '10:30',
title: '教研活动',
type: 'meeting',
tag: '教研',
location: '教研室',
description: '语文组教研活动',
details: true
},
{
startTime: '15:00',
endTime: '16:30',
title: '家长会准备',
type: 'preparation',
tag: '准备',
location: '办公室',
description: '准备家长会材料',
details: true
}
];
break;
case 2: //
data[dateStr] = [
{
startTime: '08:00',
endTime: '09:30',
title: '早读辅导',
type: 'tutoring',
tag: '辅导',
location: '教学楼A201',
description: '高一(3)班早读辅导',
details: true
},
{
startTime: '10:00',
endTime: '12:00',
title: '教研英语无痕计划OMO',
type: 'meeting',
tag: '会议',
location: 'POHCSOO007',
description: '智慧校园211楼会议室',
details: true
},
{
startTime: '14:00',
endTime: '16:00',
title: '德法内科学习课',
type: 'class',
tag: '课程',
location: 'POHCSOO007',
description: '智慧校园211楼会议室',
details: true
} , {
startTime: '08:00',
endTime: '09:30',
title: '早读辅导',
type: 'tutoring',
tag: '辅导',
location: '教学楼A201',
description: '高一(3)班早读辅导',
details: true
},
{
startTime: '10:00',
endTime: '12:00',
title: '教研英语无痕计划OMO',
type: 'meeting',
tag: '会议',
location: 'POHCSOO007',
description: '智慧校园211楼会议室',
details: true
},
{
startTime: '14:00',
endTime: '16:00',
title: '德法内科学习课',
type: 'class',
tag: '课程',
location: 'POHCSOO007',
description: '智慧校园211楼会议室',
details: true
}, {
startTime: '08:00',
endTime: '09:30',
title: '早读辅导',
type: 'tutoring',
tag: '辅导',
location: '教学楼A201',
description: '高一(3)班早读辅导',
details: true
},
{
startTime: '10:00',
endTime: '12:00',
title: '教研英语无痕计划OMO',
type: 'meeting',
tag: '会议',
location: 'POHCSOO007',
description: '智慧校园211楼会议室',
details: true
},
{
startTime: '14:00',
endTime: '16:00',
title: '德法内科学习课',
type: 'class',
tag: '课程',
location: 'POHCSOO007',
description: '智慧校园211楼会议室',
details: true
}
];
break;
case 3: //
data[dateStr] = [
{
startTime: '08:30',
endTime: '10:00',
title: '语文课',
type: 'class',
tag: '课程',
location: '教学楼A201',
description: '高一(3)班语文课',
details: true
},
{
startTime: '10:30',
endTime: '12:00',
title: '作文批改',
type: 'preparation',
tag: '批改',
location: '办公室',
description: '批改学生作文',
details: true
},
{
startTime: '14:00',
endTime: '15:30',
title: '课程设计',
type: 'preparation',
tag: '备课',
location: '办公室',
description: '准备下周课程内容',
details: true
},
{
startTime: '16:00',
endTime: '17:00',
title: '学生谈话',
type: 'counseling',
tag: '谈话',
location: '办公室',
description: '与学生张三谈话',
details: true
}
];
break;
case 4: //
data[dateStr] = [
{
startTime: '08:00',
endTime: '09:30',
title: '晨会',
type: 'meeting',
tag: '晨会',
location: '办公室',
description: '教师晨会',
details: true
},
{
startTime: '09:00',
endTime: '10:30',
title: '公开课',
type: 'class',
tag: '公开课',
location: '教学楼A201',
description: '语文公开课展示',
details: true
},
{
startTime: '11:00',
endTime: '12:00',
title: '课后辅导',
type: 'tutoring',
tag: '辅导',
location: '教学楼A201',
description: '学困生辅导',
details: true
},
{
startTime: '14:30',
endTime: '16:00',
title: '周总结会议',
type: 'meeting',
tag: '会议',
location: '会议室B302',
description: '本周工作总结',
details: true
},
{
startTime: '16:30',
endTime: '17:30',
title: '家长沟通',
type: 'counseling',
tag: '沟通',
location: '办公室',
description: '与家长电话沟通',
details: true
}
];
break;
case 5: //
data[dateStr] = [
{
startTime: '09:00',
endTime: '11:00',
title: '补课',
type: 'class',
tag: '补课',
location: '教学楼A201',
description: '高一(3)班语文补课',
details: true
}
];
break;
case 6: //
data[dateStr] = []; //
break;
}
//
data[dateStr] = [];
}
return data;
@ -480,6 +239,52 @@ const getCurrentSchedule = computed(() => {
return scheduleData[currentDate.number] || [];
});
//
const initPositionInfo = async () => {
try {
let dzZw: string[] = [];
let qtZw: string[] = [];
//
if (getJs.dzzw && typeof getJs.dzzw === "string") {
dzZw = getJs.dzzw.split(",");
}
//
if (getJs.qtzw && typeof getJs.qtzw === "string") {
qtZw = getJs.qtzw.split(",");
}
//
if (dzZw && dzZw.length > 0) {
const res = await getZwListByLx({ zwlx: "党政职务" });
dzZwLabel.value = dzZw
.map((zwId: string) => {
const zw = res.result.find((zw: any) => zwId === zw.id);
return zw ? zw.zwmc : "";
})
.filter(Boolean)
.join(", ");
}
//
if (qtZw && qtZw.length > 0) {
const res = await getZwListByLx({ zwlx: "其他职务" });
qtZwLabel.value = qtZw
.map((zwId: string) => {
const zw = res.result.find((zw: any) => zwId === zw.id);
return zw ? zw.zwmc : "";
})
.filter(Boolean)
.join(", ");
}
console.log("职务信息初始化完成:", { dzZwLabel: dzZwLabel.value, qtZwLabel: qtZwLabel.value });
} catch (error) {
console.error("初始化职务信息失败:", error);
}
};
//
const initDates = () => {
const days = ['一', '二', '三', '四', '五', '六', '日'];
@ -520,8 +325,13 @@ const goToSchedule = () => {
});
};
onMounted(() => {
onMounted(async () => {
//
await initPositionInfo();
//
initDates();
//
const today = new Date();
const currentDay = today.getDay();
@ -545,7 +355,7 @@ onMounted(() => {
overflow: hidden;
padding: 40rpx 30rpx 30rpx;
height: auto;
min-height: 320rpx;
min-height: 270rpx;
.header-gradient {
position: absolute;

View File

@ -27,7 +27,7 @@
</view>
</view>
<!-- 统计信息 -->
<!-- &lt;!&ndash; 统计信息 &ndash;&gt;
<view class="stats-info">
<view class="stat-item">
<text class="stat-label">积分</text>
@ -38,7 +38,7 @@
<text class="stat-label">工作量</text>
<text class="stat-value">{{ jsWork.ks }}课时</text>
</view>
</view>
</view>-->
<!-- 介绍文字 -->
<view class="teacher-intro">
@ -518,7 +518,7 @@ const hasPermissionDirect = (permissionKey: string) => {
overflow: hidden;
padding: 40rpx 30rpx 30rpx;
height: auto;
min-height: 320rpx;
min-height: 270rpx;
.header-gradient {
position: absolute;

View File

@ -66,35 +66,28 @@
v-for="approver in approvers"
:key="approver.id"
class="approver-item"
:class="{ 'removed': approver.isRemoved }"
>
<view class="approver-info">
<text class="order">{{ approver.order }}</text>
<text class="name">{{ approver.userName }}</text>
<text class="dept">{{ approver.deptName }}</text>
<text class="status" :class="getApproverStatusClass(approver.status)">
{{ getApproverStatusText(approver.status) }}
<text class="status" :class="getApproverStatusClass(approver.approveStatus)">
{{ getApproverStatusText(approver.approveStatus) }}
</text>
</view>
<view class="approver-actions" v-if="!approver.isRemoved">
<u-button
text="移除"
size="mini"
type="error"
@click="removeApprover(approver)"
/>
<!-- 显示审批意见和审批时间 -->
<view class="approver-detail" v-if="approver.approveRemark || approver.approveTime">
<view class="approval-info" v-if="approver.approveRemark">
<text class="info-label">审批意见</text>
<text class="info-value">{{ approver.approveRemark }}</text>
</view>
<view class="approval-info" v-if="approver.approveTime">
<text class="info-label">审批时间</text>
<text class="info-value">{{ formatTime(approver.approveTime) }}</text>
</view>
</view>
</view>
</view>
<!-- 添加审批人 -->
<view class="add-approver">
<u-button
text="添加审批人"
type="primary"
@click="showAddApproverModal = true"
/>
</view>
</view>
<!-- 抄送人 -->
@ -105,7 +98,6 @@
v-for="ccUser in ccUsers"
:key="ccUser.id"
class="cc-item"
:class="{ 'removed': ccUser.isRemoved }"
>
<view class="cc-info">
<text class="name">{{ ccUser.userName }}</text>
@ -114,25 +106,8 @@
{{ getCCStatusText(ccUser.status) }}
</text>
</view>
<view class="cc-actions" v-if="!ccUser.isRemoved">
<u-button
text="移除"
size="mini"
type="error"
@click="removeCCUser(ccUser)"
/>
</view>
</view>
</view>
<!-- 添加抄送人 -->
<view class="add-cc">
<u-button
text="添加抄送人"
type="primary"
@click="showAddCCModal = true"
/>
</view>
</view>
<!-- 操作记录 -->
@ -163,57 +138,34 @@
</view>
</view>
<!-- 保存变更按钮 -->
<view class="save-section">
<u-button
text="保存变更"
type="primary"
size="large"
@click="saveChanges"
/>
</view>
</view>
<!-- 添加审批人弹窗 -->
<u-popup v-model="showAddApproverModal" mode="bottom">
<view class="modal-content">
<view class="modal-header">
<text class="modal-title">添加审批人</text>
<u-button text="关闭" @click="showAddApproverModal = false" />
</view>
<view class="search-section">
<BasicSearch
placeholder="输入姓名或部门搜索"
@search="searchApprovers"
@select="addApprover"
/>
</view>
<view class="position-section">
<text class="position-label">插入位置</text>
<u-picker
:columns="[positionOptions]"
@confirm="onPositionConfirm"
/>
</view>
</view>
</u-popup>
<!-- 底部固定按钮 -->
<view class="bottom-actions">
<!-- 驳回按钮暂时隐藏 -->
<!-- <u-button
text="驳回"
type="error"
size="large"
@click="handleReject"
/> -->
<u-button
text="转办"
type="warning"
size="large"
@click="handleTransfer"
/>
<u-button
text="同意"
type="primary"
size="large"
@click="handleApprove"
/>
</view>
<!-- 添加抄送人弹窗 -->
<u-popup v-model="showAddCCModal" mode="bottom">
<view class="modal-content">
<view class="modal-header">
<text class="modal-title">添加抄送人</text>
<u-button text="关闭" @click="showAddCCModal = false" />
</view>
<view class="search-section">
<BasicSearch
placeholder="输入姓名或部门搜索"
@search="searchCCUsers"
@select="addCCUser"
/>
</view>
</view>
</u-popup>
<!-- 操作记录详情弹窗 -->
<u-popup v-model="showLogDetailModal" mode="center">
@ -242,11 +194,13 @@
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { ref, onMounted } from "vue";
import BasicLayout from "@/components/BasicLayout/Layout.vue";
import BasicSearch from "@/components/BasicSearch/Search.vue";
import { getGwDetailApi, searchUsersApi, saveChangesApi, getGwFlowByIdApi } from "@/api/routine/gw";
import { navigateTo } from "@/utils/uniapp";
import { getGwFlowByIdApi, gwApproveApi } from "@/api/routine/gw";
import dayjs from "dayjs";
import { useUserStore } from "@/store/modules/user";
//
interface GwInfo {
@ -264,6 +218,7 @@ interface GwInfo {
docType: string; //
urgencyLevel: string; //
tjrId: string; //
spRule?: string; //
}
interface FileInfo {
@ -274,11 +229,14 @@ interface FileInfo {
interface Approver {
id: string;
userId?: string; // ID
userName: string;
deptName: string;
order: number;
status: string;
isRemoved?: boolean;
approveStatus?: string; //
approveRemark?: string; //
approveTime?: Date; //
}
interface CCUser {
@ -286,7 +244,6 @@ interface CCUser {
userName: string;
deptName: string;
status: string;
isRemoved?: boolean;
}
interface OperationLog {
@ -300,43 +257,26 @@ interface OperationLog {
remark?: string;
}
interface User {
id: string;
userName: string;
deptName: string;
}
interface LogData {
operationType: string;
operationContent: string;
beforeChange: string;
afterChange: string;
remark?: string;
}
//
const gwId = ref("");
//
const showAddApproverModal = ref(false);
const showAddCCModal = ref(false);
const showLogDetailModal = ref(false);
// store
const { getUser, getJs } = useUserStore();
//
const gwInfo = ref<GwInfo>({} as GwInfo);
const approvers = ref<Approver[]>([]);
const ccUsers = ref<CCUser[]>([]);
const operationLogs = ref<OperationLog[]>([]);
const currentLog = ref<OperationLog>({} as OperationLog);
const selectedPosition = ref("");
//
const positionOptions = [
"在首位",
"在第二位之后",
"在第三位之后",
"在最后"
];
//
const getGwInfo = async () => {
@ -398,134 +338,19 @@ const getGwInfo = async () => {
console.log("=== getGwInfo 执行完成 ===");
};
//
const searchApprovers = async (keyword: string) => {
try {
const result = await searchUsersApi(keyword);
return result.result || [];
} catch (error) {
console.error("搜索审批人失败:", error);
return [];
}
};
//
const addApprover = (user: User) => {
const newApprover: Approver = {
...user,
order: getNextOrder(),
status: "pending",
isRemoved: false,
};
approvers.value.push(newApprover);
//
addOperationLog({
operationType: "新增审批人",
operationContent: `新增:${user.userName}(顺序${newApprover.order}`,
beforeChange: "",
afterChange: JSON.stringify(newApprover),
});
showAddApproverModal.value = false;
};
//
const removeApprover = (approver: Approver) => {
approver.isRemoved = true;
//
addOperationLog({
operationType: "移除审批人",
operationContent: `移除:${approver.userName}(顺序${approver.order}`,
beforeChange: JSON.stringify(approver),
afterChange: "",
});
//
reorderApprovers();
};
//
const searchCCUsers = async (keyword: string) => {
try {
const result = await searchUsersApi(keyword);
return result.result || [];
} catch (error) {
console.error("搜索抄送人失败:", error);
return [];
}
};
//
const addCCUser = (user: User) => {
const newCCUser: CCUser = {
...user,
status: "unread",
isRemoved: false,
};
ccUsers.value.push(newCCUser);
//
addOperationLog({
operationType: "新增抄送人",
operationContent: `新增:${user.userName}`,
beforeChange: "",
afterChange: JSON.stringify(newCCUser),
});
showAddCCModal.value = false;
};
//
const removeCCUser = (ccUser: CCUser) => {
ccUser.isRemoved = true;
//
addOperationLog({
operationType: "移除抄送人",
operationContent: `移除:${ccUser.userName}`,
beforeChange: JSON.stringify(ccUser),
afterChange: "",
});
};
//
const onPositionConfirm = (e: any) => {
selectedPosition.value = e.value[0];
};
//
const getNextOrder = (): number => {
const activeApprovers = approvers.value.filter(a => !a.isRemoved);
return activeApprovers.length + 1;
};
//
const reorderApprovers = () => {
const activeApprovers = approvers.value.filter(a => !a.isRemoved);
activeApprovers.forEach((approver, index) => {
approver.order = index + 1;
});
};
//
const addOperationLog = (log: LogData) => {
const newLog: OperationLog = {
id: Date.now().toString(),
operatorName: "当前用户", //
operationType: log.operationType,
operationContent: log.operationContent,
beforeChange: log.beforeChange,
afterChange: log.afterChange,
operationTime: new Date(),
remark: log.remark || "",
};
operationLogs.value.unshift(newLog);
};
//
const showLogDetail = (log: OperationLog) => {
@ -533,46 +358,208 @@ const showLogDetail = (log: OperationLog) => {
showLogDetailModal.value = true;
};
//
const saveChanges = async () => {
//
const handleReject = () => {
uni.showModal({
title: "驳回公文",
content: "确定要驳回这个公文吗?",
success: async (res) => {
if (res.confirm) {
try {
// API
console.log("驳回公文:", gwId.value);
uni.showToast({
title: "驳回成功",
icon: "success",
});
} catch (error) {
console.error("驳回失败:", error);
uni.showToast({
title: "驳回失败",
icon: "error",
});
}
}
},
});
};
//
const handleTransfer = () => {
//
console.log("转办公文:", gwId.value);
//
const params = {
id: gwId.value,
title: encodeURIComponent(gwInfo.value.title || ''),
xxtsInfo: encodeURIComponent(JSON.stringify({
id: gwId.value, // xxtsInfoID
// xxtsInfo
})),
gwInfo: encodeURIComponent(JSON.stringify(gwInfo.value)),
approvers: encodeURIComponent(JSON.stringify(approvers.value)),
ccUsers: encodeURIComponent(JSON.stringify(ccUsers.value)) //
};
//
uni.setStorageSync('transferData', {
xxtsInfo: { id: gwId.value },
gwInfo: gwInfo.value,
approvers: approvers.value,
ccUsers: ccUsers.value //
});
//
navigateTo(`/pages/view/routine/gwlz/gwTransfer?id=${params.id}&title=${params.title}&xxtsInfo=${params.xxtsInfo}&gwInfo=${params.gwInfo}&approvers=${params.approvers}&ccUsers=${params.ccUsers}`);
};
//
const handleApprove = () => {
uni.showModal({
title: "同意公文",
content: "请您再次确认是否同意,公文审批内容",
success: async (res) => {
if (res.confirm) {
try {
// API
await approveGw();
} catch (error) {
console.error("同意失败:", error);
uni.showToast({
title: "同意失败",
icon: "error",
});
}
}
},
});
};
// API
const approveGw = async () => {
try {
//
const activeApprovers = approvers.value.filter(a => !a.isRemoved);
if (activeApprovers.length === 0) {
uni.showToast({
title: "至少保留一名有效审批人",
icon: "error",
});
return;
}
const changeData = {
gwId: gwId.value,
approvers: approvers.value,
ccUsers: ccUsers.value,
operationLogs: operationLogs.value,
};
// API
await saveChangesApi(changeData);
uni.showToast({
title: "变更保存成功",
icon: "success",
//
uni.showLoading({
title: '正在处理...',
mask: true
});
//
await getGwInfo();
// ID - jsData
const currentUserId = getJs?.id;
if (!currentUserId) {
console.error('无法获取当前用户信息jsData:', getJs);
throw new Error('无法获取当前用户信息');
}
} catch (error) {
console.error("保存变更失败:", error);
console.log('=== 调试信息 ===');
console.log('当前用户ID:', currentUserId);
console.log('jsData详情:', getJs);
console.log('userdata详情:', getUser);
console.log('审批人列表:', approvers.value);
console.log('审批人列表长度:', approvers.value?.length || 0);
// ID
const currentUserApproverId = getCurrentUserApproverId(currentUserId);
console.log('找到的审批人ID:', currentUserApproverId);
if (!currentUserApproverId) {
console.error('无法找到当前用户的审批人记录,详细信息:');
console.error('approvers数组:', approvers.value);
console.error('当前用户ID:', currentUserId);
console.error('用户信息:', { getUser, getJs });
throw new Error('无法获取当前用户的审批人记录');
}
//
const approveData = {
xxtsId: gwId.value, // xxtsInfoID
gwId: gwInfo.value?.id || gwId.value,
spId: currentUserApproverId,
approveRemark: "同意", //
spRule: gwInfo.value?.spRule, // gwInfospRule
currentUserId: currentUserId
};
console.log('同意数据:', approveData);
// API - 使API
const response = await gwApproveApi(approveData);
console.log('API响应:', response);
//
uni.hideLoading();
if (response.resultCode === 1) {
uni.showToast({
title: "同意成功",
icon: "success",
});
//
await getGwInfo();
} else {
throw new Error(response.message || '同意失败');
}
} catch (error: any) {
//
uni.hideLoading();
console.error("同意公文失败:", error);
uni.showToast({
title: "保存失败",
title: error.message || "同意失败",
icon: "error",
});
}
};
// ID
const getCurrentUserApproverId = (currentUserId: string) => {
console.log('=== getCurrentUserApproverId 函数调试 ===');
console.log('传入的currentUserId:', currentUserId);
console.log('approvers.value:', approvers.value);
console.log('approvers.value长度:', approvers.value?.length || 0);
if (!approvers.value || approvers.value.length === 0) {
console.log('approvers数组为空或未定义返回null');
return null;
}
//
console.log('开始查找审批人记录...');
approvers.value.forEach((approver, index) => {
console.log(`审批人${index + 1}:`, {
id: approver.id,
userId: approver.userId,
userName: approver.userName,
deptName: approver.deptName,
order: approver.order,
status: approver.status,
approveStatus: approver.approveStatus
});
});
const currentUserApprover = approvers.value.find(approver => {
const matchByUserId = approver.userId === currentUserId;
const matchById = approver.id === currentUserId;
console.log(`检查审批人 ${approver.userName}:`, {
userId: approver.userId,
id: approver.id,
currentUserId: currentUserId,
matchByUserId,
matchById
});
return matchByUserId || matchById;
});
console.log('找到的审批人记录:', currentUserApprover);
const result = currentUserApprover?.id || null;
console.log('返回结果:', result);
return result;
};
//
const previewFile = (file: FileInfo) => {
//
@ -933,17 +920,11 @@ onMounted(() => {
.cc-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
border: 1px solid #eee;
border-radius: 4px;
margin-bottom: 10px;
&.removed {
opacity: 0.5;
background: #f5f5f5;
}
.approver-info,
.cc-info {
flex: 1;
@ -983,10 +964,35 @@ onMounted(() => {
}
}
.add-approver,
.add-cc {
margin-top: 15px;
text-align: center;
.approver-detail {
margin-top: 10px;
padding: 10px;
background: #f8f9fa;
border-radius: 4px;
border-left: 3px solid #007aff;
.approval-info {
display: flex;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
.info-label {
width: 80px;
color: #666;
font-size: 12px;
flex-shrink: 0;
}
.info-value {
flex: 1;
color: #333;
font-size: 12px;
word-break: break-all;
}
}
}
.log-item {
@ -1028,9 +1034,26 @@ onMounted(() => {
}
}
.save-section {
margin-top: 30px;
text-align: center;
.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;
}
.modal-content {

View File

@ -0,0 +1,418 @@
<template>
<BasicLayout>
<view class="px-15 pb-20">
<BasicForm @register="register"> </BasicForm>
</view>
<template #bottom>
<view class="flex-row items-center pb-10 pt-5">
<u-button text="取消" class="mx-15" @click="handleCancel" />
<u-button text="确认转办" class="mx-15" type="primary" @click="handleTransfer" />
</view>
</template>
</BasicLayout>
</template>
<script setup lang="ts">
import { navigateTo } from "@/utils/uniapp";
import { useForm } from "@/components/BasicForm/hooks/useForm";
import { ref, onMounted, nextTick } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { useCommonStore } from "@/store/modules/common";
import { useUserStore } from "@/store/modules/user";
import { gwTransferApi } from "@/api/routine/gw";
// ID
const gwId = ref<string>("");
//
const gwTitle = ref<string>("");
// store
const { getUser, getJs } = useUserStore();
//
const xxtsInfo = ref<any>(null);
const gwInfo = ref<any>(null);
const approvers = ref<any[]>([]);
const ccUsers = ref<any[]>([]);
//
const [register, { getValue, setValue }] = useForm({
schema: [
{
title: "转办信息",
},
{
field: "gwTitle",
label: "公文标题",
component: "BasicInput",
componentProps: {
placeholder: "公文标题",
readonly: true,
disabled: true,
},
},
{
field: "currentApprovers",
label: "当前审批人",
component: "BasicInput",
componentProps: {
placeholder: "当前审批人",
readonly: true,
disabled: true,
},
},
{
field: "currentCcUsers",
label: "当前抄送人",
component: "BasicInput",
componentProps: {
placeholder: "当前抄送人",
readonly: true,
disabled: true,
},
},
{
field: "transferTo",
label: "转办人",
component: "BasicJsPicker",
defaultValue: [],
required: true,
componentProps: {
multiple: true,
placeholder: "请选择转办人",
title: "选择转办人",
searchPlaceholder: "输入教师姓名搜索",
onChange: async (value: any) => {
//
setValue({ transferTo: value });
}
},
},
{
field: "ccTo",
label: "抄送人",
component: "BasicJsPicker",
defaultValue: [],
required: false,
componentProps: {
multiple: true,
placeholder: "请选择抄送人(可选)",
title: "选择抄送人",
searchPlaceholder: "输入教师姓名搜索",
onChange: async (value: any) => {
//
setValue({ ccTo: value });
}
},
},
{
field: "transferReason",
label: "转办描述",
component: "BasicInput",
required: true,
componentProps: {
placeholder: "请输入转办原因和描述",
type: "textarea",
rows: 5,
},
},
],
});
//
onLoad((options) => {
if (options?.id) {
gwId.value = options.id;
}
if (options?.title) {
gwTitle.value = decodeURIComponent(options.title);
}
//
if (options?.xxtsInfo) {
try {
xxtsInfo.value = JSON.parse(decodeURIComponent(options.xxtsInfo));
} catch (error) {
console.error('解析xxtsInfo失败:', error);
}
}
if (options?.gwInfo) {
try {
gwInfo.value = JSON.parse(decodeURIComponent(options.gwInfo));
} catch (error) {
console.error('解析gwInfo失败:', error);
}
}
if (options?.approvers) {
try {
approvers.value = JSON.parse(decodeURIComponent(options.approvers));
} catch (error) {
console.error('解析approvers失败:', error);
}
}
if (options?.ccUsers) {
try {
ccUsers.value = JSON.parse(decodeURIComponent(options.ccUsers));
} catch (error) {
console.error('解析ccUsers失败:', error);
}
}
});
//
onMounted(async () => {
// tick
await nextTick();
//
if (gwTitle.value) {
setValue({ gwTitle: gwTitle.value });
}
//
if (approvers.value && approvers.value.length > 0) {
const approverNames = approvers.value.map(approver => approver.userName).join('、');
setValue({ currentApprovers: approverNames });
}
//
if (ccUsers.value && ccUsers.value.length > 0) {
const ccUserNames = ccUsers.value.map(ccUser => ccUser.userName).join('、');
setValue({ currentCcUsers: ccUserNames });
}
//
if (!xxtsInfo.value || !gwInfo.value || !approvers.value.length || !ccUsers.value.length) {
await loadTransferData();
}
});
//
const loadTransferData = async () => {
try {
//
const storedData = uni.getStorageSync('transferData');
if (storedData) {
xxtsInfo.value = storedData.xxtsInfo;
gwInfo.value = storedData.gwInfo;
approvers.value = storedData.approvers;
ccUsers.value = storedData.ccUsers || [];
console.log('从本地存储加载转办数据:', storedData);
}
} catch (error) {
console.error('加载转办数据失败:', error);
}
};
// ID
const getCurrentUserApproverId = (currentUserId: string) => {
if (!approvers.value || approvers.value.length === 0) {
return null;
}
//
const currentUserApprover = approvers.value.find(approver =>
approver.userId === currentUserId || approver.id === currentUserId
);
return currentUserApprover?.id || null;
};
//
const handleCancel = () => {
navigateTo("/pages/view/routine/gwlz/gwFlow?id=" + gwId.value);
};
//
const handleTransfer = async () => {
try {
const value = await getValue();
//
if (!validateForm(value)) {
return;
}
//
uni.showLoading({
title: '正在转办...',
mask: true
});
// ID
const currentUserId = getJs?.id || getUser?.id;
if (!currentUserId) {
throw new Error('无法获取当前用户信息');
}
//
const transferData = {
// 1. xxtsInfoidxxtsIdyfzc_xxtsdbZtB
xxtsId: xxtsInfo.value?.id,
// 2. gwInfoidgwIdyfzc_gwgwStatusC
gwId: gwInfo.value?.id || gwId.value,
// 3. approversuserId=userdataIDspIdyfzc_lcgl_sp
// approveSatusapprovedapproveTmeapproveRemark
spId: getCurrentUserApproverId(currentUserId),
//
transferTo: value.transferTo,
ccTo: value.ccTo || [], //
spRule: gwInfo.value?.spRule, // gwInfospRule
transferReason: value.transferReason,
transferTime: new Date().toISOString(),
currentUserId: currentUserId,
};
console.log('转办数据:', transferData);
console.log('转办人数据类型:', typeof value.transferTo);
console.log('转办人数据内容:', JSON.stringify(value.transferTo));
console.log('抄送人数据类型:', typeof value.ccTo);
console.log('抄送人数据内容:', JSON.stringify(value.ccTo));
console.log('xxtsInfo:', xxtsInfo.value);
console.log('gwInfo:', gwInfo.value);
console.log('approvers:', approvers.value);
console.log('ccUsers:', ccUsers.value);
console.log('当前用户ID:', currentUserId);
console.log('当前用户对应的审批人ID:', getCurrentUserApproverId(currentUserId));
// API
await gwTransferApi(transferData);
//
uni.hideLoading();
//
uni.showToast({
title: "转办成功",
icon: "success",
});
//
setTimeout(() => {
navigateTo("/pages/view/routine/gwlz/gwFlow?id=" + gwId.value);
}, 1500);
} catch (error) {
//
uni.hideLoading();
console.error("转办失败:", error);
uni.showToast({
title: "转办失败",
icon: "error",
});
}
};
//
const validateForm = (value: any) => {
//
if (!value.transferTo || value.transferTo.length === 0) {
uni.showToast({
title: "请选择转办人",
icon: "error",
});
return false;
}
//
if (!value.transferReason || value.transferReason.trim() === "") {
uni.showToast({
title: "请输入转办描述",
icon: "error",
});
return false;
}
//
if (!xxtsInfo.value?.id) {
uni.showToast({
title: "缺少必要的数据信息",
icon: "error",
});
return false;
}
if (!gwInfo.value?.id) {
uni.showToast({
title: "缺少公文信息",
icon: "error",
});
return false;
}
if (!approvers.value || approvers.value.length === 0) {
uni.showToast({
title: "缺少审批人信息",
icon: "error",
});
return false;
}
//
return true;
};
</script>
<style lang="scss" scoped>
.transfer-form {
background: #fff;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.form-title {
font-size: 18px;
font-weight: bold;
color: #333;
margin-bottom: 20px;
text-align: center;
border-bottom: 2px solid #007aff;
padding-bottom: 10px;
}
.form-item {
margin-bottom: 20px;
.label {
display: block;
font-weight: 500;
color: #333;
margin-bottom: 8px;
}
.required {
color: #ff4d4f;
margin-left: 4px;
}
}
.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>