Merge branch 'master' of http://119.29.194.155:8894/zwq/zhxy-jsd
# Conflicts: # src/config.ts
This commit is contained in:
commit
a8a0edc5d4
@ -1,84 +1,91 @@
|
|||||||
// 参数接口
|
// 参数接口
|
||||||
|
|
||||||
// 响应接口
|
// 响应接口
|
||||||
import {get, post} from "@/utils/request";
|
import { get, post } from "@/utils/request";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取服务器时间
|
* 获取服务器时间
|
||||||
*/
|
*/
|
||||||
export const xqgwFindAllApi = async () => {
|
export const xqgwFindAllApi = async () => {
|
||||||
return await get("/api/xqgw/findAll");
|
return await get("/api/xqgw/findAll");
|
||||||
};
|
};
|
||||||
export const xqxjFindAllApi = async () => {
|
export const xqxjFindAllApi = async () => {
|
||||||
return await get("/api/xqxj/findAll");
|
return await get("/api/xqxj/findAll");
|
||||||
};
|
};
|
||||||
export const findAllNjBjTreeApi = async () => {
|
export const findAllNjBjTreeApi = async () => {
|
||||||
return await get("/api/nj/findAllNjBjTree");
|
return await get("/api/nj/findAllNjBjTree");
|
||||||
};
|
};
|
||||||
export const kmFindAllApi = async () => {
|
export const kmFindAllApi = async () => {
|
||||||
return await get("/api/km/findAll");
|
return await get("/api/km/findAll");
|
||||||
};
|
};
|
||||||
export const findAllXxXqNjTree = async () => {
|
export const findAllXxXqNjTree = async () => {
|
||||||
return await get("/api/nj/findAllXxXqNjTree");
|
return await get("/api/nj/findAllXxXqNjTree");
|
||||||
};
|
};
|
||||||
export const findAllNjBjTree = async () => {
|
export const findAllNjBjTree = async () => {
|
||||||
return await get("/api/nj/findAllNjBjTree");
|
return await get("/api/nj/findAllNjBjTree");
|
||||||
};
|
};
|
||||||
export const jsConfirmJsDataApi = async (params: any) => {
|
export const jsConfirmJsDataApi = async (params: any) => {
|
||||||
return await post("/api/js/confirmJsData", params);
|
return await post("/api/js/confirmJsData", params);
|
||||||
};
|
};
|
||||||
export const jsdFindPageTaskApi = async (params: any) => {
|
export const jsdFindPageTaskApi = async (params: any) => {
|
||||||
return await get("/api/jsd/findPageTask", params);
|
return await get("/api/jsd/findPageTask", params);
|
||||||
};
|
};
|
||||||
export const rwflFindRwlxsByRwId = async (params: any) => {
|
export const rwflFindRwlxsByRwId = async (params: any) => {
|
||||||
return await get("/api/rwlx/findRwlxsByRwId", params);
|
return await get("/api/rwlx/findRwlxsByRwId", params);
|
||||||
}
|
};
|
||||||
export const rwzxSaveApi = async (params: any) => {
|
export const rwzxSaveApi = async (params: any) => {
|
||||||
return await post("/api/rwzx/save", params);
|
return await post("/api/rwzx/save", params);
|
||||||
};
|
};
|
||||||
export const rwzxExecutedInfoByRwIdAndJsApi = async (params: any) => {
|
export const rwzxExecutedInfoByRwIdAndJsApi = async (params: any) => {
|
||||||
return await get("/api/rwzx/executedInfoByRwIdAndJs", params);
|
return await get("/api/rwzx/executedInfoByRwIdAndJs", params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const rwFindInfoByRwId = async (params: any) => {
|
export const rwFindInfoByRwId = async (params: any) => {
|
||||||
return await get("/api/rw/findInfoByRwId", params);
|
return await get("/api/rw/findInfoByRwId", params);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const fractionRuleApi = async () => {
|
export const fractionRuleApi = async () => {
|
||||||
return await get(
|
return await get(
|
||||||
"/api/fractionRule/findAllByItemId?itemId=CDFDED2A704F46E2A4D7E8816968BD23"
|
"/api/fractionRule/findAllByItemId?itemId=CDFDED2A704F46E2A4D7E8816968BD23"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export const fractionRuleApi1 = async () => {
|
export const fractionRuleApi1 = async () => {
|
||||||
return await get(
|
return await get(
|
||||||
"/api/fractionRule/findAllByItemId?itemId=B96A0FA22C414F71A3E1CDCA7E206B10"
|
"/api/fractionRule/findAllByItemId?itemId=B96A0FA22C414F71A3E1CDCA7E206B10"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 查询教师信息
|
// 查询教师信息
|
||||||
export const jsdfindJsByPhoneApi = async (params: any) => {
|
export const jsdfindJsByPhoneApi = async (params: any) => {
|
||||||
return await get("/api/js/findJsByPhone", params);
|
return await get("/api/js/findJsByPhone", params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 选课列表
|
// 选课列表
|
||||||
export const jsdXkListApi = async (params: any) => {
|
export const jsdXkListApi = async (params: any) => {
|
||||||
return await get("/mobile/js/xk/list", params);
|
return await get("/mobile/js/xk/list", params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 选课列表
|
// 选课列表
|
||||||
export const jsdXkkcSaveApi = async (params: any) => {
|
export const jsdXkkcSaveApi = async (params: any) => {
|
||||||
return await post("/api/xkkc/save", params);
|
return await post("/api/xkkc/save", params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 选课学生列表
|
// 选课学生列表
|
||||||
export const jsdXkXsListApi = async (params: any) => {
|
export const jsdXkXsListApi = async (params: any) => {
|
||||||
return await get("/mobile/js/xkxs/list", params);
|
return await get("/mobile/js/xkxs/list", params);
|
||||||
|
};
|
||||||
|
export const mobilejlstudentListApi = async (params: any) => {
|
||||||
|
return await get("/mobile/jl/studentList", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mobilejllistApi = async (params: any) => {
|
||||||
|
const res = await get("/mobile/jl/list", params);
|
||||||
|
return res.result;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交点名信息
|
// 提交点名信息
|
||||||
export const jsdXkdmListApi = async (params: any) => {
|
export const jsdXkdmListApi = async (params: any) => {
|
||||||
return await post("/mobile/js/xkdm/add", params);
|
return await post("/mobile/js/xkdm/add", params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取待办列表
|
// 获取待办列表
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
const ip: string = "127.0.0.1:8897";
|
// const ip: string = "192.168.239.1:8897";
|
||||||
|
const ip: string = "yufangzc.com";
|
||||||
// const ip: string = "yufangzc.com";
|
// const ip: string = "yufangzc.com";
|
||||||
const fwqip: string = "yufangzc.com";
|
const fwqip: string = "yufangzc.com";
|
||||||
//打包服务器接口代理标识
|
//打包服务器接口代理标识
|
||||||
|
|||||||
@ -359,21 +359,21 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/view/notice/index",
|
"path": "pages/view/notice/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "通知公告",
|
"navigationBarTitleText": "发布接龙",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/view/notice/detail",
|
"path": "pages/view/notice/detail",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "通知详情",
|
"navigationBarTitleText": "接龙详情",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/view/notice/publish",
|
"path": "pages/view/notice/publish",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "发布通知",
|
"navigationBarTitleText": "接龙推送",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -206,7 +206,7 @@ const sections = reactive<Section[]>([
|
|||||||
{
|
{
|
||||||
id: "r7",
|
id: "r7",
|
||||||
icon: "file-text-fill-2",
|
icon: "file-text-fill-2",
|
||||||
text: "选课详情",
|
text: "课程介绍",
|
||||||
show: true,
|
show: true,
|
||||||
path: "/pages/base/groupTeaching/xkList",
|
path: "/pages/base/groupTeaching/xkList",
|
||||||
},
|
},
|
||||||
@ -218,6 +218,13 @@ const sections = reactive<Section[]>([
|
|||||||
show: true,
|
show: true,
|
||||||
path: "/pages/base/groupTeaching/dmXkList",
|
path: "/pages/base/groupTeaching/dmXkList",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "r8",
|
||||||
|
icon: "draftfill",
|
||||||
|
text: "发布接龙",
|
||||||
|
show: true,
|
||||||
|
path: "/pages/view/notice/index",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -226,29 +226,6 @@ if (getFile.rgqkList && getFile.rgqkList.length > 0) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 手动触发计算所有项目的任岗年限
|
|
||||||
const calculateAllPositionYears = () => {
|
|
||||||
education.xl.forEach((item: any, index: number) => {
|
|
||||||
if (item.value.gwrzkstime) {
|
|
||||||
const years = calculatePositionYears(
|
|
||||||
item.value.gwrzkstime,
|
|
||||||
item.value.gwrzjstime
|
|
||||||
);
|
|
||||||
item.value.gwrznx = years;
|
|
||||||
console.log(`表单项${index}计算结果:`, {
|
|
||||||
gwrzkstime: item.value.gwrzkstime,
|
|
||||||
gwrzjstime: item.value.gwrzjstime,
|
|
||||||
gwrznx: years,
|
|
||||||
是否为0: years === "0",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// 没有开始时间时,清空任岗年限
|
|
||||||
item.value.gwrznx = "";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
forceUpdateKey.value++;
|
|
||||||
};
|
|
||||||
|
|
||||||
function addEducation() {
|
function addEducation() {
|
||||||
education.xl.push({ value: {} });
|
education.xl.push({ value: {} });
|
||||||
// 强制重新渲染
|
// 强制重新渲染
|
||||||
|
|||||||
@ -1,120 +1,81 @@
|
|||||||
<!-- src/pages/view/notice/index.vue -->
|
<!-- src/pages/view/notice/index.vue -->
|
||||||
<template>
|
<template>
|
||||||
<view class="notice-list-page">
|
<view class="jl-list-page">
|
||||||
|
<!-- 列表内容 -->
|
||||||
<BasicListLayout @register="register">
|
<BasicListLayout @register="register">
|
||||||
<template #default="{ data }">
|
<template v-slot="{ data }">
|
||||||
<view class="notice-card" @click="goToDetail(data.id)">
|
<view class="jl-card" @click="goToDetail(data.id)">
|
||||||
<view class="card-header">
|
<view class="card-header">
|
||||||
<text class="notice-title">{{ data.title }}</text>
|
<text class="jl-title">{{ data.jlmc }}</text>
|
||||||
<text class="notice-status" :class="getStatusClass(data.status)">{{
|
<text class="jl-status" :class="getStatusClass(data.jlStatus)">
|
||||||
data.statusText
|
{{ getStatusText(data.jlStatus) }}
|
||||||
}}</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="card-body">
|
<view class="card-body">
|
||||||
<!-- 可选:显示封面缩略图 -->
|
|
||||||
<image
|
<image
|
||||||
v-if="data.coverImage"
|
v-if="data.jlfm"
|
||||||
:src="data.coverImage"
|
:src="imagUrl(data.jlfm)"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
class="cover-thumbnail"
|
class="cover-thumbnail"
|
||||||
></image>
|
></image>
|
||||||
<text class="notice-excerpt">{{ data.excerpt }}</text>
|
<rich-text class="jl-excerpt" :nodes="data.jlms"></rich-text>
|
||||||
</view>
|
</view>
|
||||||
<view class="card-footer">
|
<view class="card-footer">
|
||||||
<text class="footer-item">发布者: {{ data.publisher }}</text>
|
<text class="footer-item">发布者: {{ data.jsxm }}</text>
|
||||||
<text class="footer-item">{{ data.publishTime }}</text>
|
<text class="footer-item">{{ formatTime(data.jlFbtime) }}</text>
|
||||||
<text class="footer-item" v-if="data.target"
|
<text class="footer-item" v-if="data.bjmc"
|
||||||
>范围: {{ data.target }}</text
|
>范围: {{ data.njmc + data.bjmc }}</text
|
||||||
>
|
>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
<template #bottom>
|
||||||
|
<view class="white-bg-color py-5">
|
||||||
|
<view class="flex-row items-center pb-10 pt-5">
|
||||||
|
<u-button
|
||||||
|
text="新增接龙"
|
||||||
|
class="mx-15"
|
||||||
|
type="primary"
|
||||||
|
@click="goToPublish"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
</BasicListLayout>
|
</BasicListLayout>
|
||||||
|
|
||||||
<!-- 新建通知按钮 -->
|
|
||||||
<view class="fab-button" @click="goToPublish">
|
|
||||||
<uni-icons type="plusempty" size="24" color="#fff"></uni-icons>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from "vue";
|
|
||||||
import { useLayout } from "@/components/BasicListLayout/hooks/useLayout";
|
import { useLayout } from "@/components/BasicListLayout/hooks/useLayout";
|
||||||
|
import { mobilejllistApi } from "@/api/base/server";
|
||||||
|
import { imagUrl } from "@/utils";
|
||||||
|
import BasicDragButton from "@/components/BasicDragButton/DragButton.vue";
|
||||||
|
|
||||||
interface NoticeItem {
|
interface JlItem {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
jlmc: string; // 接龙名称
|
||||||
excerpt: string; // 内容摘要
|
jlms: string; // 接龙描述
|
||||||
status: "published" | "draft" | "ended"; // 状态
|
jlStatus: string; // 发布状态:A已发布,B暂存
|
||||||
statusText: string; // 状态文字
|
jlFbr: string; // 发布人
|
||||||
publisher: string;
|
jlFbtime: string; // 发布时间
|
||||||
publishTime: string;
|
jlfm: string; // 接龙封面
|
||||||
coverImage?: string; // 封面图 URL (可选)
|
njmc: string;
|
||||||
target?: string; // 通知范围 (可选)
|
bjmc: string; // 班级名称
|
||||||
|
jlkstime: string; // 接龙开始时间
|
||||||
|
jljstime: string; // 接龙结束时间
|
||||||
|
jsxm?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模拟获取通知列表数据的 API 函数
|
// 使用 BasicListLayout
|
||||||
const fetchNoticeList = async (params: any): Promise<any> => {
|
|
||||||
// 返回类型改为 Promise<any>
|
|
||||||
console.log("Fetching notice list with params:", params);
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
// 根据 params.pageNo 和 params.pageSize 模拟分页
|
|
||||||
const pageNo = params.pageNo || 1;
|
|
||||||
const pageSize = params.pageSize || 10;
|
|
||||||
const total = 35; // 模拟总数
|
|
||||||
const mockData: NoticeItem[] = [];
|
|
||||||
const startIndex = (pageNo - 1) * pageSize;
|
|
||||||
|
|
||||||
for (let i = 0; i < pageSize; i++) {
|
|
||||||
const currentIndex = startIndex + i;
|
|
||||||
if (currentIndex >= total) break; // 超出总数则停止
|
|
||||||
|
|
||||||
const status =
|
|
||||||
currentIndex % 3 === 0
|
|
||||||
? "draft"
|
|
||||||
: currentIndex % 3 === 1
|
|
||||||
? "published"
|
|
||||||
: "ended";
|
|
||||||
mockData.push({
|
|
||||||
id: `notice_${currentIndex + 1}`,
|
|
||||||
title: `重要通知标题 ${currentIndex + 1}`,
|
|
||||||
excerpt: `这是通知 ${currentIndex + 1} 的内容摘要,只显示一部分...`,
|
|
||||||
status: status,
|
|
||||||
statusText:
|
|
||||||
status === "draft"
|
|
||||||
? "草稿"
|
|
||||||
: status === "published"
|
|
||||||
? "已发布"
|
|
||||||
: "已结束",
|
|
||||||
publisher: "教务处",
|
|
||||||
publishTime: `2024-06-${String(
|
|
||||||
18 - Math.floor(currentIndex / 5)
|
|
||||||
).padStart(2, "0")}`,
|
|
||||||
target: currentIndex % 2 === 0 ? "一年级3班" : "全体教师",
|
|
||||||
// coverImage: i % 3 === 0 ? '/static/mock/cover.png' : undefined
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
message: "获取成功",
|
|
||||||
resultCode: 1,
|
|
||||||
rows: mockData,
|
|
||||||
total: total,
|
|
||||||
});
|
|
||||||
}, 800); // 模拟网络延迟
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const [register, { reload }] = useLayout({
|
const [register, { reload }] = useLayout({
|
||||||
api: fetchNoticeList,
|
api: mobilejllistApi, // 必须提供 api,即使使用了 query
|
||||||
|
componentProps: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 跳转到详情页
|
// 跳转到详情页
|
||||||
const goToDetail = (noticeId: string) => {
|
const goToDetail = (jlId: string) => {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/view/notice/detail?id=${noticeId}`,
|
url: `/pages/view/notice/detail?id=${jlId}`,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -126,21 +87,37 @@ const goToPublish = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 根据状态获取对应的 CSS 类
|
// 根据状态获取对应的 CSS 类
|
||||||
const getStatusClass = (status: "published" | "draft" | "ended") => {
|
const getStatusClass = (status: string) => {
|
||||||
if (status === "published") return "status-published";
|
if (status === "A") return "status-published";
|
||||||
if (status === "draft") return "status-draft";
|
if (status === "B") return "status-draft";
|
||||||
if (status === "ended") return "status-ended";
|
return "status-ended";
|
||||||
return "";
|
};
|
||||||
|
|
||||||
|
// 根据状态获取状态文字
|
||||||
|
const getStatusText = (status: string) => {
|
||||||
|
if (status === "A") return "已发布";
|
||||||
|
if (status === "B") return "暂存";
|
||||||
|
return "已结束";
|
||||||
|
};
|
||||||
|
|
||||||
|
// 格式化时间
|
||||||
|
const formatTime = (timeStr: string) => {
|
||||||
|
if (!timeStr) return "";
|
||||||
|
const date = new Date(timeStr);
|
||||||
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(
|
||||||
|
2,
|
||||||
|
"0"
|
||||||
|
)}-${String(date.getDate()).padStart(2, "0")}`;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.notice-list-page {
|
.jl-list-page {
|
||||||
position: relative; // 为了 FAB 定位
|
position: relative; // 为了 FAB 定位
|
||||||
min-height: 100vh; // 确保 FAB 总在视图内
|
min-height: 100vh; // 确保 FAB 总在视图内
|
||||||
}
|
}
|
||||||
|
|
||||||
.notice-card {
|
.jl-card {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
@ -155,7 +132,7 @@ const getStatusClass = (status: "published" | "draft" | "ended") => {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
|
||||||
.notice-title {
|
.jl-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
@ -169,7 +146,7 @@ const getStatusClass = (status: "published" | "draft" | "ended") => {
|
|||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notice-status {
|
.jl-status {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -180,9 +157,11 @@ const getStatusClass = (status: "published" | "draft" | "ended") => {
|
|||||||
&.status-published {
|
&.status-published {
|
||||||
background-color: #19be6b; // 绿色-已发布
|
background-color: #19be6b; // 绿色-已发布
|
||||||
}
|
}
|
||||||
|
|
||||||
&.status-draft {
|
&.status-draft {
|
||||||
background-color: #ff9f0a; // 橙色-草稿
|
background-color: #ff9f0a; // 橙色-暂存
|
||||||
}
|
}
|
||||||
|
|
||||||
&.status-ended {
|
&.status-ended {
|
||||||
background-color: #999999; // 灰色-已结束
|
background-color: #999999; // 灰色-已结束
|
||||||
}
|
}
|
||||||
@ -198,7 +177,8 @@ const getStatusClass = (status: "published" | "draft" | "ended") => {
|
|||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
float: left; // 文字环绕图片
|
float: left; // 文字环绕图片
|
||||||
}
|
}
|
||||||
.notice-excerpt {
|
|
||||||
|
.jl-excerpt {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #666;
|
color: #666;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@ -209,12 +189,6 @@ const getStatusClass = (status: "published" | "draft" | "ended") => {
|
|||||||
-webkit-line-clamp: 3;
|
-webkit-line-clamp: 3;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
}
|
}
|
||||||
// 清除浮动影响(如果用了 float)
|
|
||||||
// &::after {
|
|
||||||
// content: "";
|
|
||||||
// display: table;
|
|
||||||
// clear: both;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-footer {
|
.card-footer {
|
||||||
@ -232,11 +206,8 @@ const getStatusClass = (status: "published" | "draft" | "ended") => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FAB 按钮样式
|
// FAB 按钮样式 - 由 DragButton 组件处理定位
|
||||||
.fab-button {
|
.fab-button {
|
||||||
position: fixed;
|
|
||||||
right: 20px;
|
|
||||||
bottom: 40px; // 根据需要调整距离底部的距离
|
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
background-color: #4477ee;
|
background-color: #4477ee;
|
||||||
@ -245,6 +216,7 @@ const getStatusClass = (status: "published" | "draft" | "ended") => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
||||||
z-index: 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 空列表样式已由 BasicListLayout 组件处理,移除此样式 */
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
<view class="cover-upload-wrapper">
|
<view class="cover-upload-wrapper">
|
||||||
<CustomUpload
|
<CustomUpload
|
||||||
field="coverImage"
|
field="coverImage"
|
||||||
:value="formData.coverImage"
|
:value="formData.coverImage ? imagUrl(formData.coverImage) : ''"
|
||||||
@select="handleCoverSelected"
|
@select="handleCoverSelected"
|
||||||
@close="handleCoverClosed"
|
@close="handleCoverClosed"
|
||||||
>
|
>
|
||||||
@ -80,45 +80,35 @@
|
|||||||
<view class="add-icon"
|
<view class="add-icon"
|
||||||
><uni-icons type="plusempty" size="20" color="#ccc"></uni-icons
|
><uni-icons type="plusempty" size="20" color="#ccc"></uni-icons
|
||||||
></view>
|
></view>
|
||||||
<text class="placeholder-text"
|
<text class="placeholder-text">添加图文/视频/文件</text>
|
||||||
>添加图文/视频/文件/公众号/小程序等</text
|
|
||||||
>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="info-card">
|
<view class="info-card">
|
||||||
<picker
|
<view class="card-header picker-header" @click="showClassTree">
|
||||||
mode="selector"
|
<text class="section-title">按名单填写</text>
|
||||||
:range="combinedClassRange"
|
<view class="target-class">
|
||||||
:value="selectedClassIndex"
|
<text :class="{ placeholder: !formData.targetClass }">{{
|
||||||
@change="onClassPickerChange"
|
formData.targetClass || "请选择班级"
|
||||||
>
|
}}</text>
|
||||||
<view class="card-header picker-header">
|
<uni-icons type="right" size="16" color="#999"></uni-icons>
|
||||||
<text class="section-title">按名单填写</text>
|
|
||||||
<view class="target-class">
|
|
||||||
<text :class="{ placeholder: !formData.targetClass }">{{
|
|
||||||
formData.targetClass || "请选择班级"
|
|
||||||
}}</text>
|
|
||||||
<uni-icons type="right" size="16" color="#999"></uni-icons>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</picker>
|
</view>
|
||||||
<view class="name-tags">
|
<view class="name-tags">
|
||||||
<text
|
<text
|
||||||
v-for="name in formData.targetNames"
|
v-for="(name, index) in displayNames"
|
||||||
:key="name"
|
:key="name + index"
|
||||||
class="name-tag"
|
class="name-tag"
|
||||||
>{{ name }}</text
|
>{{ name }}</text
|
||||||
>
|
>
|
||||||
<button
|
</view>
|
||||||
v-if="formData.targetNames.length > 0"
|
<view
|
||||||
size="mini"
|
v-if="formData.targetNames.length > maxDisplayCount"
|
||||||
type="default"
|
class="more-btn-container"
|
||||||
class="modify-btn"
|
>
|
||||||
@click="handleModifyNames"
|
<button size="mini" class="more-btn-full" @click="showAllStudents">
|
||||||
>
|
更多({{ formData.targetNames.length - maxDisplayCount }})
|
||||||
修改
|
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -165,17 +155,64 @@
|
|||||||
|
|
||||||
<!-- Bottom slot -->
|
<!-- Bottom slot -->
|
||||||
<template #bottom>
|
<template #bottom>
|
||||||
<view class="bottom-actions">
|
<view class="bottom-actions">
|
||||||
<button class="action-btn draft-btn" @click="saveDraft">保存草稿</button>
|
<button class="action-btn draft-btn" @click="saveDraft">
|
||||||
<button class="action-btn preview-btn" @click="previewNotice">
|
保存草稿
|
||||||
预览
|
</button>
|
||||||
</button>
|
<button class="action-btn preview-btn" @click="previewNotice">
|
||||||
<button class="action-btn publish-btn" @click="publishNotice">
|
预览
|
||||||
立即发布
|
</button>
|
||||||
</button>
|
<button class="action-btn publish-btn" @click="publishNotice">
|
||||||
</view>
|
立即发布
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 班级选择树 -->
|
||||||
|
<BasicTree
|
||||||
|
ref="treeRef"
|
||||||
|
:range="treeData"
|
||||||
|
idKey="key"
|
||||||
|
rangeKey="title"
|
||||||
|
title="选择班级"
|
||||||
|
:multiple="true"
|
||||||
|
:selectParent="false"
|
||||||
|
@confirm="onTreeConfirm"
|
||||||
|
@cancel="onTreeCancel"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 学生名单弹窗 -->
|
||||||
|
<view
|
||||||
|
v-if="showStudentModal"
|
||||||
|
class="student-modal-mask"
|
||||||
|
@click="closeStudentModal"
|
||||||
|
>
|
||||||
|
<view class="student-modal" @click.stop>
|
||||||
|
<view class="student-modal-header">
|
||||||
|
<text class="modal-title">全部学生名单</text>
|
||||||
|
<text class="student-count"
|
||||||
|
>共{{ formData.targetNames.length }}人</text
|
||||||
|
>
|
||||||
|
<uni-icons
|
||||||
|
type="closeempty"
|
||||||
|
size="20"
|
||||||
|
color="#999"
|
||||||
|
@click="closeStudentModal"
|
||||||
|
class="close-icon"
|
||||||
|
></uni-icons>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y class="student-modal-content">
|
||||||
|
<view class="all-student-tags">
|
||||||
|
<text
|
||||||
|
v-for="(name, index) in formData.targetNames"
|
||||||
|
:key="name + index"
|
||||||
|
class="student-tag"
|
||||||
|
>{{ name }}</text
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</BasicLayout>
|
</BasicLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -183,6 +220,10 @@
|
|||||||
import { ref, reactive, computed } from "vue";
|
import { ref, reactive, computed } from "vue";
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
import CustomUpload from "/src/components/BasicUpload/CustomUpload.vue";
|
import CustomUpload from "/src/components/BasicUpload/CustomUpload.vue";
|
||||||
|
import BasicTree from "@/components/BasicTree/Tree.vue";
|
||||||
|
import { attachmentUpload } from "@/api/system/upload";
|
||||||
|
import { imagUrl } from "@/utils";
|
||||||
|
import { findAllNjBjTree, mobilejlstudentListApi } from "@/api/base/server";
|
||||||
|
|
||||||
interface Attachment {
|
interface Attachment {
|
||||||
name: string;
|
name: string;
|
||||||
@ -200,6 +241,8 @@ interface FormData {
|
|||||||
targetClass: string;
|
targetClass: string;
|
||||||
targetNames: string[];
|
targetNames: string[];
|
||||||
targetStudentIds: string[];
|
targetStudentIds: string[];
|
||||||
|
targetNjIds: string[]; // 年级ID数组
|
||||||
|
targetBjIds: string[]; // 班级ID数组
|
||||||
signatureRequired: boolean;
|
signatureRequired: boolean;
|
||||||
startTime: string;
|
startTime: string;
|
||||||
endTime: string;
|
endTime: string;
|
||||||
@ -215,6 +258,8 @@ const formData = reactive<FormData>({
|
|||||||
targetClass: "",
|
targetClass: "",
|
||||||
targetNames: [],
|
targetNames: [],
|
||||||
targetStudentIds: [],
|
targetStudentIds: [],
|
||||||
|
targetNjIds: [],
|
||||||
|
targetBjIds: [],
|
||||||
signatureRequired: false,
|
signatureRequired: false,
|
||||||
startTime: "",
|
startTime: "",
|
||||||
endTime: "",
|
endTime: "",
|
||||||
@ -225,38 +270,40 @@ const signatureStatusText = computed(() => {
|
|||||||
return formData.signatureRequired ? "启用" : "不启用";
|
return formData.signatureRequired ? "启用" : "不启用";
|
||||||
});
|
});
|
||||||
|
|
||||||
const classList = ref([
|
// 树形数据
|
||||||
{ id: "g1c1", name: "一年级1班" },
|
const treeData = ref([]);
|
||||||
{ id: "g1c2", name: "一年级2班" },
|
const treeRef = ref();
|
||||||
{ id: "g1c3", name: "一年级3班" },
|
|
||||||
{ id: "g1c4", name: "一年级4班" },
|
|
||||||
{ id: "g1c5", name: "一年级5班" },
|
|
||||||
{ id: "g2c1", name: "二年级1班" },
|
|
||||||
{ id: "g2c2", name: "二年级2班" },
|
|
||||||
{ id: "g2c3", name: "二年级3班" },
|
|
||||||
{ id: "g3c1", name: "三年级1班" },
|
|
||||||
{ id: "g3c2", name: "三年级2班" },
|
|
||||||
{ id: "g3c3", name: "三年级3班" },
|
|
||||||
{ id: "g3c4", name: "三年级4班" },
|
|
||||||
{ id: "g4c1", name: "四年级1班" },
|
|
||||||
{ id: "g4c2", name: "四年级2班" },
|
|
||||||
{ id: "g5c1", name: "五年级1班" },
|
|
||||||
{ id: "g5c2", name: "五年级2班" },
|
|
||||||
{ id: "g5c3", name: "五年级3班" },
|
|
||||||
{ id: "g6c1", name: "六年级1班" },
|
|
||||||
{ id: "g6c2", name: "六年级2班" },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const combinedClassRange = computed(() => {
|
// 学生显示相关
|
||||||
return classList.value.map((cls) => cls.name);
|
const maxDisplayCount = 24; // 最多显示24个学生(4行×6列)
|
||||||
|
const showStudentModal = ref(false);
|
||||||
|
|
||||||
|
// 计算显示的学生名单(最多显示前24个)
|
||||||
|
const displayNames = computed(() => {
|
||||||
|
return formData.targetNames.slice(0, maxDisplayCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedClassIndex = computed(() => {
|
// 加载树形数据
|
||||||
const index = classList.value.findIndex(
|
const loadTreeData = async () => {
|
||||||
(cls) => cls.name === formData.targetClass
|
try {
|
||||||
);
|
const res = await findAllNjBjTree();
|
||||||
return index >= 0 ? index : 0;
|
if (res.resultCode === 1 && res.result) {
|
||||||
});
|
// 转换数据格式以适配 BasicTree 组件
|
||||||
|
treeData.value = res.result.map((item: any) => ({
|
||||||
|
key: item.key,
|
||||||
|
title: item.title,
|
||||||
|
children: item.children || [],
|
||||||
|
}));
|
||||||
|
console.log("树形数据加载成功:", treeData.value);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("加载树形数据失败:", error);
|
||||||
|
uni.showToast({ title: "加载班级数据失败", icon: "error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 在组件挂载时加载数据
|
||||||
|
loadTreeData();
|
||||||
|
|
||||||
const fetchStudentsByClass = async (className: string): Promise<string[]> => {
|
const fetchStudentsByClass = async (className: string): Promise<string[]> => {
|
||||||
console.log(`模拟获取班级 [${className}] 的学生列表...`);
|
console.log(`模拟获取班级 [${className}] 的学生列表...`);
|
||||||
@ -281,40 +328,42 @@ const fetchStudentsByClass = async (className: string): Promise<string[]> => {
|
|||||||
return mockStudents;
|
return mockStudents;
|
||||||
};
|
};
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {});
|
||||||
if (options && options.id) {
|
|
||||||
noticeId.value = options.id;
|
|
||||||
uni.setNavigationBarTitle({ title: "编辑通知" });
|
|
||||||
formData.title = "关于五一放假的通知 (编辑)";
|
|
||||||
formData.content = "根据校历安排,现将2024年五一劳动节放假安排通知如下...";
|
|
||||||
formData.targetClass = "二年级1班";
|
|
||||||
formData.targetNames = ["张三", "李四"];
|
|
||||||
formData.targetStudentIds = ["s201-mock", "s202-mock"];
|
|
||||||
formData.signatureRequired = true;
|
|
||||||
formData.startTime = "2024-04-30 18:00:00";
|
|
||||||
formData.endTime = "2024-05-05 23:59:59";
|
|
||||||
if (formData.targetClass && noticeId.value) {
|
|
||||||
fetchStudentsByClass(formData.targetClass).then((students) => {
|
|
||||||
formData.targetNames = students;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uni.setNavigationBarTitle({ title: "发布通知" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleCoverSelected = (e: any) => {
|
const handleCoverSelected = async (e: any) => {
|
||||||
console.log("选择封面 (CustomUpload):", e);
|
|
||||||
if (e.tempFilePaths && e.tempFilePaths.length > 0) {
|
if (e.tempFilePaths && e.tempFilePaths.length > 0) {
|
||||||
formData.coverImage = e.tempFilePaths[0];
|
const tempFilePath = e.tempFilePaths[0];
|
||||||
console.log("封面临时路径:", formData.coverImage);
|
|
||||||
|
try {
|
||||||
|
uni.showLoading({ title: "上传中..." });
|
||||||
|
|
||||||
|
// 直接使用 tempFilePath 作为 Blob 传给接口
|
||||||
|
const uploadResult: any = await attachmentUpload(tempFilePath as any);
|
||||||
|
|
||||||
|
if (
|
||||||
|
uploadResult.resultCode === 1 &&
|
||||||
|
uploadResult.result &&
|
||||||
|
uploadResult.result.length > 0
|
||||||
|
) {
|
||||||
|
// 保存原始的 filePath(用于提交到服务器)
|
||||||
|
const originalPath = uploadResult.result[0].filePath;
|
||||||
|
formData.coverImage = originalPath;
|
||||||
|
uni.showToast({ title: "封面上传成功", icon: "success" });
|
||||||
|
} else {
|
||||||
|
throw new Error("上传响应格式异常");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
uni.showToast({ title: "封面上传失败", icon: "error" });
|
||||||
|
formData.coverImage = null;
|
||||||
|
} finally {
|
||||||
|
uni.hideLoading();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error("无法从选择事件中获取封面路径:", e);
|
console.error("无法从选择事件中获取封面路径:", e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCoverClosed = (field: string) => {
|
const handleCoverClosed = (field: string) => {
|
||||||
console.log(`删除封面 (CustomUpload): field=${field}`);
|
|
||||||
if (field === "coverImage") {
|
if (field === "coverImage") {
|
||||||
formData.coverImage = null;
|
formData.coverImage = null;
|
||||||
}
|
}
|
||||||
@ -324,47 +373,74 @@ const addAttachment = () => {
|
|||||||
uni.chooseFile({
|
uni.chooseFile({
|
||||||
count: 5,
|
count: 5,
|
||||||
type: "all",
|
type: "all",
|
||||||
success: (res) => {
|
success: async (res) => {
|
||||||
const tempFiles = res.tempFiles;
|
const tempFiles = res.tempFiles;
|
||||||
if (Array.isArray(tempFiles) && tempFiles.length > 0) {
|
if (Array.isArray(tempFiles) && tempFiles.length > 0) {
|
||||||
tempFiles.forEach((file: any) => {
|
uni.showLoading({ title: "上传中..." });
|
||||||
let fileType = "file";
|
|
||||||
const fileName = file.name || "";
|
|
||||||
const fileExtension = fileName.split(".").pop()?.toLowerCase();
|
|
||||||
|
|
||||||
if (
|
try {
|
||||||
["png", "jpg", "jpeg", "gif", "bmp", "webp"].includes(
|
for (const file of tempFiles) {
|
||||||
fileExtension || ""
|
const fileInfo = file as any; // 强制类型转换避免类型检查错误
|
||||||
)
|
let fileType = "file";
|
||||||
) {
|
const fileName = fileInfo.name || "";
|
||||||
fileType = "image";
|
const fileExtension = fileName.split(".").pop()?.toLowerCase();
|
||||||
} else if (
|
|
||||||
["mp4", "mov", "avi", "wmv", "flv"].includes(fileExtension || "")
|
if (
|
||||||
) {
|
["png", "jpg", "jpeg", "gif", "bmp", "webp"].includes(
|
||||||
fileType = "video";
|
fileExtension || ""
|
||||||
} else if (
|
)
|
||||||
["mp3", "wav", "aac", "ogg"].includes(fileExtension || "")
|
) {
|
||||||
) {
|
fileType = "image";
|
||||||
fileType = "audio";
|
} else if (
|
||||||
|
["mp4", "mov", "avi", "wmv", "flv"].includes(fileExtension || "")
|
||||||
|
) {
|
||||||
|
fileType = "video";
|
||||||
|
} else if (
|
||||||
|
["mp3", "wav", "aac", "ogg"].includes(fileExtension || "")
|
||||||
|
) {
|
||||||
|
fileType = "audio";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
fileInfo.type &&
|
||||||
|
typeof fileInfo.type === "string" &&
|
||||||
|
(fileInfo.type.startsWith("image/") ||
|
||||||
|
fileInfo.type.startsWith("video/") ||
|
||||||
|
fileInfo.type.startsWith("audio/"))
|
||||||
|
) {
|
||||||
|
fileType = fileInfo.type.split("/")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接使用文件路径作为 Blob 传给接口
|
||||||
|
const uploadResult: any = await attachmentUpload(
|
||||||
|
fileInfo.path as any
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
uploadResult.resultCode === 1 &&
|
||||||
|
uploadResult.result &&
|
||||||
|
uploadResult.result.length > 0
|
||||||
|
) {
|
||||||
|
// 保存原始的 filePath(用于提交到服务器)
|
||||||
|
const originalPath = uploadResult.result[0].filePath;
|
||||||
|
formData.attachments.push({
|
||||||
|
name: fileName,
|
||||||
|
type: fileType,
|
||||||
|
url: originalPath, // 保存原始路径
|
||||||
|
size: fileInfo.size,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: `${fileName} 上传失败`, icon: "error" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
uni.showToast({ title: "附件上传完成", icon: "success" });
|
||||||
file.type &&
|
} catch (error) {
|
||||||
typeof file.type === "string" &&
|
console.error("附件上传失败:", error);
|
||||||
(file.type.startsWith("image/") ||
|
uni.showToast({ title: "附件上传失败", icon: "error" });
|
||||||
file.type.startsWith("video/") ||
|
} finally {
|
||||||
file.type.startsWith("audio/"))
|
uni.hideLoading();
|
||||||
) {
|
}
|
||||||
fileType = file.type.split("/")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
formData.attachments.push({
|
|
||||||
name: fileName,
|
|
||||||
type: fileType,
|
|
||||||
url: file.path,
|
|
||||||
size: file.size,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
console.log("未选择任何文件或返回结果异常,或 tempFiles 不是数组");
|
console.log("未选择任何文件或返回结果异常,或 tempFiles 不是数组");
|
||||||
}
|
}
|
||||||
@ -391,38 +467,124 @@ const getAttachmentIcon = (type: string): string => {
|
|||||||
|
|
||||||
const previewAttachment = (attachment: Attachment) => {
|
const previewAttachment = (attachment: Attachment) => {
|
||||||
console.log("预览附件:", attachment);
|
console.log("预览附件:", attachment);
|
||||||
uni.showToast({ title: `预览 ${attachment.name} 功能待实现`, icon: "none" });
|
// 如果是图片类型,可以预览
|
||||||
|
if (attachment.type === "image") {
|
||||||
|
const fullUrl = imagUrl(attachment.url);
|
||||||
|
uni.previewImage({
|
||||||
|
urls: [fullUrl],
|
||||||
|
current: fullUrl,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: `预览 ${attachment.name} 功能待实现`,
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClassPickerChange = async (e: any) => {
|
// 显示班级选择树
|
||||||
const index = e.detail.value;
|
const showClassTree = () => {
|
||||||
const selectedClass = classList.value[index];
|
if (treeRef.value) {
|
||||||
if (selectedClass && selectedClass.name !== formData.targetClass) {
|
treeRef.value._show();
|
||||||
formData.targetClass = selectedClass.name;
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 树形选择确认
|
||||||
|
const onTreeConfirm = async (selectedItems: any[]) => {
|
||||||
|
console.log("选择的班级:", selectedItems);
|
||||||
|
if (selectedItems.length > 0) {
|
||||||
|
// 处理多选情况
|
||||||
|
const classNames = selectedItems.map((item) => item.title);
|
||||||
|
formData.targetClass = classNames.join(", ");
|
||||||
formData.targetNames = [];
|
formData.targetNames = [];
|
||||||
formData.targetStudentIds = [];
|
formData.targetStudentIds = [];
|
||||||
|
formData.targetNjIds = [];
|
||||||
|
formData.targetBjIds = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const students = await fetchStudentsByClass(formData.targetClass);
|
uni.showLoading({ title: "获取学生列表中..." });
|
||||||
formData.targetNames = students;
|
|
||||||
|
// 提取年级ID和班级ID
|
||||||
|
const njIds: string[] = [];
|
||||||
|
const bjIds: string[] = [];
|
||||||
|
|
||||||
|
selectedItems.forEach((item) => {
|
||||||
|
// 如果选择的是班级(有parents表示是班级)
|
||||||
|
if (item.parents && item.parents.length > 0) {
|
||||||
|
const njId = item.parents[0].key; // 年级ID:parents[0].key
|
||||||
|
const bjId = item.key; // 班级ID:item.key
|
||||||
|
njIds.push(njId);
|
||||||
|
bjIds.push(bjId);
|
||||||
|
console.log(
|
||||||
|
`选择班级: ${item.title}, 年级ID: ${njId}, 班级ID: ${bjId}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (njIds.length > 0 && bjIds.length > 0) {
|
||||||
|
// 对年级ID去重
|
||||||
|
const uniqueNjIds = [...new Set(njIds)];
|
||||||
|
|
||||||
|
// 保存选择的年级ID和班级ID到formData中
|
||||||
|
formData.targetNjIds = uniqueNjIds;
|
||||||
|
formData.targetBjIds = bjIds;
|
||||||
|
|
||||||
|
// 调用接口获取学生列表
|
||||||
|
const params = {
|
||||||
|
njId: uniqueNjIds.join(","),
|
||||||
|
bjId: bjIds.join(","),
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await mobilejlstudentListApi(params);
|
||||||
|
|
||||||
|
if (response && response.resultCode === 1 && response.result) {
|
||||||
|
// 提取学生姓名,尝试多个可能的字段名
|
||||||
|
const studentNames = response.result.map(
|
||||||
|
(student: any) =>
|
||||||
|
student.xsxm ||
|
||||||
|
student.name ||
|
||||||
|
student.studentName ||
|
||||||
|
student.xm ||
|
||||||
|
"未知姓名"
|
||||||
|
);
|
||||||
|
formData.targetNames = studentNames;
|
||||||
|
formData.targetStudentIds = response.result.map(
|
||||||
|
(student: any) =>
|
||||||
|
student.id || student.xsId || student.studentId || ""
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error("获取学生列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uni.hideLoading();
|
||||||
|
uni.showToast({
|
||||||
|
title: `已选择 ${selectedItems.length} 个班级`,
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("获取学生列表失败:", error);
|
console.error("获取学生列表失败:", error);
|
||||||
uni.showToast({ title: "获取学生列表失败", icon: "none" });
|
uni.hideLoading();
|
||||||
|
uni.showToast({ title: "获取学生列表失败", icon: "error" });
|
||||||
|
// 如果接口失败,使用模拟数据
|
||||||
|
formData.targetNames = await fetchStudentsByClass(formData.targetClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleModifyNames = () => {
|
// 树形选择取消
|
||||||
const selectedClassObj = classList.value.find(
|
const onTreeCancel = () => {
|
||||||
(cls) => cls.name === formData.targetClass
|
console.log("取消选择班级");
|
||||||
);
|
};
|
||||||
if (!selectedClassObj) {
|
|
||||||
uni.showToast({ title: "请先选择班级", icon: "none" });
|
// 显示全部学生
|
||||||
return;
|
const showAllStudents = () => {
|
||||||
}
|
showStudentModal.value = true;
|
||||||
const classId = selectedClassObj.id;
|
};
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/view/notice/selectStudents?classId=${classId}`,
|
// 关闭学生弹窗
|
||||||
});
|
const closeStudentModal = () => {
|
||||||
|
showStudentModal.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSignatureChange = (e: any) => {
|
const handleSignatureChange = (e: any) => {
|
||||||
@ -464,13 +626,25 @@ const previewNotice = () => {
|
|||||||
|
|
||||||
const publishNotice = () => {
|
const publishNotice = () => {
|
||||||
if (!validateForm()) return;
|
if (!validateForm()) return;
|
||||||
console.log("发布通知", formData);
|
|
||||||
uni.showLoading({ title: "发布中..." });
|
// 准备发布数据,包含年级ID和班级ID
|
||||||
setTimeout(() => {
|
const publishData = {
|
||||||
uni.hideLoading();
|
...formData,
|
||||||
uni.showToast({ title: "发布成功 (模拟)", icon: "success" });
|
njIds: formData.targetNjIds.join(","), // 年级ID字符串
|
||||||
uni.navigateBack();
|
bjIds: formData.targetBjIds.join(","), // 班级ID字符串
|
||||||
}, 1000);
|
};
|
||||||
|
|
||||||
|
console.log("发布通知数据:", publishData);
|
||||||
|
console.log("年级ID:", publishData.njIds);
|
||||||
|
console.log("班级ID:", publishData.bjIds);
|
||||||
|
|
||||||
|
// TODO: 调用发布接口
|
||||||
|
// uni.showLoading({ title: "发布中..." });
|
||||||
|
// setTimeout(() => {
|
||||||
|
// uni.hideLoading();
|
||||||
|
// uni.showToast({ title: "发布成功 (模拟)", icon: "success" });
|
||||||
|
// uni.navigateBack();
|
||||||
|
// }, 1000);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -734,8 +908,7 @@ const publishNotice = () => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
min-height: 30px;
|
min-height: 30px;
|
||||||
|
|
||||||
.name-tag,
|
.name-tag {
|
||||||
.modify-btn {
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -746,29 +919,10 @@ const publishNotice = () => {
|
|||||||
flex-basis: calc((100% - 50px) / 6);
|
flex-basis: calc((100% - 50px) / 6);
|
||||||
height: 28px;
|
height: 28px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
}
|
|
||||||
|
|
||||||
.name-tag {
|
|
||||||
background-color: #f4f4f5;
|
background-color: #f4f4f5;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modify-btn {
|
|
||||||
background-color: #ecf5ff;
|
|
||||||
color: #409eff;
|
|
||||||
border: 1px solid #d9ecff;
|
|
||||||
padding: 0;
|
|
||||||
margin-left: 0;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
&::after {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-spinner {
|
.loading-spinner {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
@ -778,6 +932,26 @@ const publishNotice = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.more-btn-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-btn-full {
|
||||||
|
width: 100%;
|
||||||
|
height: 35px;
|
||||||
|
background-color: #fff2e8;
|
||||||
|
color: #e6a23c;
|
||||||
|
border: 1px solid #f5dab1;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
&::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: #ffecd1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.list-item-card {
|
.list-item-card {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
.uni-datetime-picker,
|
.uni-datetime-picker,
|
||||||
@ -887,7 +1061,76 @@ const publishNotice = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.target-class text.placeholder {
|
.target-class text.placeholder {
|
||||||
color: #909399;
|
color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 学生名单弹窗样式 */
|
||||||
|
.student-modal-mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-modal {
|
||||||
|
width: 90%;
|
||||||
|
max-height: 80%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-modal-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-count {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-modal-content {
|
||||||
|
max-height: 400px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-student-tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-tag {
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #f4f4f5;
|
||||||
|
color: #909399;
|
||||||
|
min-width: 60px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user