批量推送

This commit is contained in:
郭庆泰
2026-08-16 13:42:26 +08:00
parent c612d4297a
commit 0c093076a4
66 changed files with 4847 additions and 1627 deletions
+92 -93
View File
@@ -1,89 +1,84 @@
<template>
<div class="page-card">
<!-- 面包屑 ( sponsor 端一致: 首页 / XXX / 当前页) -->
<!-- 面包屑 -->
<div class="breadcrumb">
首页 / 项目管理 / <span class="current">{{ isEdit ? '编辑项目' : '新建项目' }}</span>
</div>
<!-- 第一区块项目信息 -->
<el-card shadow="never" class="new-card">
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="project-form">
<!-- ========== 第一区块项目信息 ========== -->
<div class="new-card-title">项目信息</div>
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入项目名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编号" prop="projectNo">
<el-input v-model="form.projectNo" placeholder="请输入项目编号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="项目形式" prop="projectForm">
<el-select v-model="form.projectForm" placeholder="请选择" style="width:100%">
<el-option label="线" value="线" />
<el-option label="线下" value="线下" />
<el-option label="线上+线下" value="线上+线下" />
<el-option label="其他" value="其他" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="总场次/总期数" prop="totalSessions">
<el-input-number v-model="form.totalSessions" :min="1" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="总金额(元)" prop="totalAmount">
<el-input-number v-model="form.totalAmount" :min="0" :precision="2" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="管理费(元)">
<el-input-number v-model="form.manageFee" :min="0" :precision="2" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="开始时间" prop="startTime">
<el-date-picker v-model="form.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结束时间" prop="endTime">
<el-date-picker v-model="form.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<!-- 支持单位 -->
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="提交截止(天)">
<el-input-number v-model="form.submitDeadlineDays" :min="0" controls-position="right" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="支持单位">
<el-select v-model="form.orgId" placeholder="请选择赞助公司" filterable clearable style="width:100%" @change="onSupporterPick">
<el-option v-for="u in supporterOptions" :key="u.userId"
:label="`${u.userName}${u.nickName ? ' (' + u.nickName + ')' : ''}`"
:value="u.userId" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入项目名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编号" prop="projectNo">
<el-input v-model="form.projectNo" placeholder="请输入项目编号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="项目形式" prop="projectForm">
<el-select v-model="form.projectForm" placeholder="请选择" style="width:100%">
<el-option label="线上" value="线上" />
<el-option label="线" value="线" />
<el-option label="线上+线下" value="线上+线下" />
<el-option label="其他" value="其他" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="总场次/总期数" prop="totalSessions">
<el-input-number v-model="form.totalSessions" :min="1" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="总金额(元)" prop="totalAmount">
<el-input-number v-model="form.totalAmount" :min="0" :precision="2" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="管理费(元)">
<el-input-number v-model="form.manageFee" :min="0" :precision="2" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="开始时间" prop="startTime">
<el-date-picker v-model="form.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结束时间" prop="endTime">
<el-date-picker v-model="form.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12">
<el-form-item label="提交截止(天)">
<el-input-number v-model="form.submitDeadlineDays" :min="0" controls-position="right" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="支持单位">
<el-select v-model="form.orgId" placeholder="请选择赞助公司" filterable clearable style="width:100%" @change="onSupporterPick">
<el-option v-for="u in supporterOptions" :key="u.userId"
:label="`${u.userName}${u.nickName ? ' (' + u.nickName + ')' : ''}`"
:value="u.userId" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 第二区块角色劳务设置 -->
<el-card shadow="never" class="new-card">
<!-- ========== 第二区块角色劳务设置 ========== -->
<div class="new-card-title">角色劳务设置</div>
<div class="hint-text">
<p>*角色劳务设置针对该项目所有会议生效</p>
@@ -100,17 +95,14 @@
</el-select>
<el-input v-if="r.role === '其他'" v-model="r.customName" placeholder="角色名" class="role-custom" />
<el-input-number v-model="r.amount" :min="0" :precision="2" placeholder="劳务金额" class="role-amount" />
<!-- 行尾按钮: 每行末尾 [增加角色] + [删除本行] (不靠右, 紧贴字段) -->
<div class="row-actions">
<el-button link type="primary" @click="addRoleRow">增加角色</el-button>
<el-button link type="danger" :disabled="form.roleRows.length<=1" @click="removeRoleRowAt(idx)">删除角色</el-button>
</div>
</div>
<p class="hint-text">*当选择其他时,需手动填写角色名称,显示填写框</p>
</el-card>
<!-- 第三区块公告文件 -->
<el-card shadow="never" class="new-card">
<!-- ========== 第三区块公告文件 ========== -->
<div class="new-card-title">公告文件</div>
<p class="hint-text">*勾选公告类型后上传对应文件发布公告时可同时发布多个类型</p>
<div class="notice-list">
@@ -143,9 +135,9 @@
</div>
</div>
<p class="hint-text">*名称规则:公告文件类型+取项目编号的后两段+项目名称</p>
</el-card>
</el-form>
<!-- 底部按钮 (与 sponsor 工具栏风格一致) -->
<!-- 底部按钮 -->
<div class="form-actions">
<el-button @click="confirmCancel">取消</el-button>
<el-button type="warning" :loading="submitting" @click="submit('publish')">保存并发布公告</el-button>
@@ -183,7 +175,7 @@ const form = reactive({
projectName: '', projectNo: '', projectForm: '',
totalSessions: 0, totalAmount: 0, manageFee: 0,
startTime: '', endTime: '',
// 赞助公司 (TODO: 下拉源应改为 biz_org,orgType='sponsor', 当前是 sys_user)
// 赞助公司 (TODO 后续: 下拉源应改为 biz_org,orgType='sponsor' 列表, 当前是 sys_user)
orgId: null,
orgName: '',
// 提交截止(天)
@@ -286,7 +278,7 @@ async function loadSupporters(query = '') {
const params = { roleType: 'sponsor', pageNum: 1, pageSize: 50 }
if (query) params.userName = query
const r = await listSupporters(params)
supporterOptions.value = r.rows || r.data || []
supporterOptions.value = (r.data && r.data.rows) || r.rows || []
} catch (e) { supporterOptions.value = [] }
}
@@ -454,18 +446,25 @@ async function submit(mode = 'save') {
</script>
<style scoped>
/* 1:1 抄 sponsor/SponsorProjects.vue */
/* 整页面板 (与 People.vue 风格一致, 1 层) */
.page-card { background: #fff; padding: 16px 20px; border-radius: 6px; border: 1px solid #f0f0f0; }
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
.breadcrumb .current { color: #262626; font-weight: 500; }
/* 卡片分块 (与 sponsor 一致: 左边竖线标识 + 标题) */
.new-card { margin-bottom: 14px; border: 1px solid #f0f0f0; border-radius: 4px; }
.new-card :deep(.el-card__body) { padding: 16px 20px; }
/* 表单 (整页一个 form) */
.project-form { max-width: 100%; }
/* 章节标题 (替换原 .new-card 容器, 用分隔线分割 3 块) */
.new-card-title {
font-size: 14px; font-weight: 600; color: #262626; margin-bottom: 12px;
padding-left: 8px; border-left: 3px solid var(--brand-primary, #1890ff); line-height: 1;
font-size: 14px;
font-weight: 600;
color: #262626;
margin: 16px 0 12px;
padding-left: 8px;
border-left: 3px solid var(--brand-primary);
line-height: 1;
}
.new-card-title:first-child { margin-top: 0; }
.hint-text { font-size: 12px; color: #909399; margin: 8px 0; line-height: 1.6; }
.hint-text p { margin-bottom: 4px; }
@@ -499,6 +498,6 @@ async function submit(mode = 'save') {
.notice-actions .el-button { padding: 2px 6px; font-size: 12px; }
.notice-disabled { flex: 1; color: #c0c4cc; font-size: 13px; padding: 8px 0; }
/* 底部按钮 (居中, 与 sponsor 风格一致) */
/* 底部按钮 */
.form-actions { display: flex; justify-content: center; gap: 16px; padding: 20px 0 4px; border-top: 1px solid #f0f0f0; margin-top: 8px; }
</style>