批量推送
This commit is contained in:
@@ -1,31 +1,31 @@
|
||||
<template>
|
||||
<div class="manager-accounts">
|
||||
<div class="page-card">
|
||||
<div class="desc">查看当前登录账号、修改个人信息与密码</div>
|
||||
<el-descriptions :column="2" border style="margin-bottom: 24px">
|
||||
<el-descriptions-item label="账号">{{ profile.userName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="姓名">{{ profile.nickName || profile.userName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="角色">{{ (profile.roleGroup || '').split(',')[0] || '合规人员' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">{{ profile.status === '0' ? '正常' : '停用' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="手机">{{ profile.phonenumber || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="邮箱">{{ profile.email || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间" :span="2">{{ profile.createTime || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div class="page-card manager-accounts">
|
||||
<div class="breadcrumb">首页 / 账号管理</div>
|
||||
<p class="page-sub">查看当前登录账号、修改个人信息与密码</p>
|
||||
|
||||
<el-form :model="form" label-width="120px" style="max-width:600px" :rules="rules" ref="formRef">
|
||||
<div class="section-title">修改个人信息</div>
|
||||
<el-form-item label="姓名" prop="nickName"><el-input v-model="form.nickName" placeholder="请输入姓名" /></el-form-item>
|
||||
<el-form-item label="手机号" prop="phonenumber"><el-input v-model="form.phonenumber" placeholder="请输入手机号" /></el-form-item>
|
||||
<el-form-item label="邮箱" prop="email"><el-input v-model="form.email" placeholder="请输入邮箱" /></el-form-item>
|
||||
<el-descriptions :column="2" border style="margin-bottom: 24px">
|
||||
<el-descriptions-item label="账号">{{ profile.userName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="姓名">{{ profile.nickName || profile.userName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="角色">{{ (profile.roleGroup || '').split(',')[0] || '合规人员' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">{{ profile.status === '0' ? '正常' : '停用' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="手机">{{ profile.phonenumber || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="邮箱">{{ profile.email || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间" :span="2">{{ profile.createTime || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<div class="section-title">修改密码</div>
|
||||
<el-form-item label="原密码" prop="oldPassword"><el-input v-model="form.oldPassword" type="password" show-password placeholder="请输入原密码" /></el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword"><el-input v-model="form.newPassword" type="password" show-password placeholder="请输入新密码" /></el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword"><el-input v-model="form.confirmPassword" type="password" show-password placeholder="请再次输入新密码" /></el-form-item>
|
||||
<div class="form-tip">* 密码长度 6-20 位,支持数字、字母、特殊字符;留空表示不修改密码</div>
|
||||
<el-form-item><el-button type="primary" :loading="saving" @click="onSave">保存</el-button><el-button @click="onCancel">取消</el-button></el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-form :model="form" label-width="120px" style="max-width:600px" :rules="rules" ref="formRef">
|
||||
<div class="section-title">修改个人信息</div>
|
||||
<el-form-item label="姓名" prop="nickName"><el-input v-model="form.nickName" placeholder="请输入姓名" /></el-form-item>
|
||||
<el-form-item label="手机号" prop="phonenumber"><el-input v-model="form.phonenumber" placeholder="请输入手机号" /></el-form-item>
|
||||
<el-form-item label="邮箱" prop="email"><el-input v-model="form.email" placeholder="请输入邮箱" /></el-form-item>
|
||||
|
||||
<div class="section-title">修改密码</div>
|
||||
<el-form-item label="原密码" prop="oldPassword"><el-input v-model="form.oldPassword" type="password" show-password placeholder="请输入原密码" /></el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword"><el-input v-model="form.newPassword" type="password" show-password placeholder="请输入新密码" /></el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword"><el-input v-model="form.confirmPassword" type="password" show-password placeholder="请再次输入新密码" /></el-form-item>
|
||||
<div class="filter-tip">* 密码长度 6-20 位,支持数字、字母、特殊字符;留空表示不修改密码</div>
|
||||
<el-form-item><el-button type="primary" :loading="saving" @click="onSave">保存</el-button><el-button @click="onCancel">取消</el-button></el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -92,9 +92,15 @@ onMounted(loadProfile)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-accounts { padding: 16px; }
|
||||
.page-card { background: #fff; border-radius: 6px; padding: 24px; border: 1px solid #ebeef5; }
|
||||
.desc { color: #909399; font-size: 13px; margin-bottom: 16px; }
|
||||
.section-title { font-weight: 600; margin: 16px 0 12px; padding-left: 8px; border-left: 3px solid var(--brand-primary); }
|
||||
.form-tip { color: #909399; font-size: 12px; margin-bottom: 12px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.page-sub { font-size: 13px; color: #909399; margin-bottom: 16px; }
|
||||
.filter-tip { color: #909399; font-size: 12px; margin-bottom: 12px; }
|
||||
.section-title {
|
||||
font-weight: 600;
|
||||
margin: 16px 0 12px;
|
||||
padding-left: 8px;
|
||||
border-left: 3px solid var(--brand-primary);
|
||||
}
|
||||
</style>
|
||||
@@ -1,39 +1,41 @@
|
||||
<template>
|
||||
<div class="manager-exec-intent">
|
||||
<div class="page-card">
|
||||
<div class="desc">查看专家对项目的执行意向(含待签约/已签约/已拒绝/已退出)</div>
|
||||
<el-form inline :model="q">
|
||||
<el-form-item label="项目编号:"><el-input v-model="q.projectNo" clearable /></el-form-item>
|
||||
<el-form-item label="项目名称:"><el-input v-model="q.projectName" clearable /></el-form-item>
|
||||
<el-form-item label="姓名:"><el-input v-model="q.name" clearable /></el-form-item>
|
||||
<el-form-item label="工作单位:"><el-input v-model="q.workUnit" clearable /></el-form-item>
|
||||
<el-form-item label="手机号:"><el-input v-model="q.phone" clearable /></el-form-item>
|
||||
<el-form-item label="签约状态:">
|
||||
<el-select v-model="q.onboardStatus" clearable>
|
||||
<el-option label="待签约" value="待签约" /><el-option label="已签约" value="已签约" />
|
||||
<el-option label="已拒绝" value="已拒绝" /><el-option label="已退出" value="已退出" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item><el-button type="primary" @click="load">查找</el-button><el-button @click="reset">重置</el-button></el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="page-card">
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column prop="projectNo" label="意向项目编号" width="140" />
|
||||
<el-table-column prop="projectName" label="意向项目名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="name" label="姓名" width="100" />
|
||||
<el-table-column prop="workUnit" label="工作单位" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="department" label="部门" width="120" />
|
||||
<el-table-column prop="position" label="职务" width="100" />
|
||||
<el-table-column prop="phone" label="手机号" width="130" />
|
||||
<el-table-column label="签约状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.onboardStatus==='已签约' ? 'success' : row.onboardStatus==='已拒绝' ? 'danger' : row.onboardStatus==='已退出' ? 'info' : 'warning'">{{ row.onboardStatus }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="170" />
|
||||
</el-table>
|
||||
<div class="page-card manager-exec-intent">
|
||||
<div class="breadcrumb">首页 / 执行意向</div>
|
||||
|
||||
<!-- ========== 筛选区 (与 People.vue 风格一致) ========== -->
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="项目编号"><el-input v-model="q.projectNo" clearable /></el-form-item>
|
||||
<el-form-item label="项目名称"><el-input v-model="q.projectName" clearable /></el-form-item>
|
||||
<el-form-item label="姓名"><el-input v-model="q.name" clearable /></el-form-item>
|
||||
<el-form-item label="工作单位"><el-input v-model="q.workUnit" clearable /></el-form-item>
|
||||
<el-form-item label="手机号"><el-input v-model="q.phone" clearable /></el-form-item>
|
||||
<el-form-item label="签约状态">
|
||||
<el-select v-model="q.onboardStatus" clearable>
|
||||
<el-option label="待签约" value="待签约" /><el-option label="已签约" value="已签约" />
|
||||
<el-option label="已拒绝" value="已拒绝" /><el-option label="已退出" value="已退出" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item><el-button type="primary" @click="load">查找</el-button><el-button @click="reset">重置</el-button></el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- ========== 表格 (与 People.vue 风格一致, 无 page-card 包裹) ========== -->
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column prop="projectNo" label="意向项目编号" width="140" />
|
||||
<el-table-column prop="projectName" label="意向项目名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="name" label="姓名" width="100" />
|
||||
<el-table-column prop="workUnit" label="工作单位" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="department" label="部门" width="120" />
|
||||
<el-table-column prop="position" label="职务" width="100" />
|
||||
<el-table-column prop="phone" label="手机号" width="130" />
|
||||
<el-table-column label="签约状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.onboardStatus==='已签约' ? 'success' : row.onboardStatus==='已拒绝' ? 'danger' : row.onboardStatus==='已退出' ? 'info' : 'warning'">{{ row.onboardStatus }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="170" />
|
||||
</el-table>
|
||||
<div class="pager">
|
||||
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,8 +64,9 @@ onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-exec-intent { padding: 16px; }
|
||||
.page-card { background: #fff; border-radius: 6px; padding: 16px; border: 1px solid #ebeef5; margin-bottom: 12px; }
|
||||
.page-title { font-size: 20px; font-weight: 600; margin-bottom: 4px; }
|
||||
.desc { color: #909399; font-size: 13px; margin-bottom: 12px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
</style>
|
||||
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<!--
|
||||
角色: 🟨 合规 服务机构查看 (manager/executor-orgs)
|
||||
说明: 原 manager/Orgs.vue 拆出 executor 一支, 仅查看
|
||||
接口: bizList('org', q)
|
||||
-->
|
||||
<div class="page-card manager-executor-orgs">
|
||||
<div class="breadcrumb">首页 / 服务机构管理</div>
|
||||
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="公司名称">
|
||||
<el-input v-model="q.orgName" placeholder="输入公司名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="税号/统一社会信用代码">
|
||||
<el-input v-model="q.taxNo" placeholder="输入税号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="合作状态">
|
||||
<el-select v-model="q.status" placeholder="请选择" clearable>
|
||||
<el-option label="0正常" value="0" />
|
||||
<el-option label="合作中" value="合作中" />
|
||||
<el-option label="1禁用" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column prop="orgName" label="公司名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="address" label="公司地址" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column prop="taxNo" label="税号/统一社会信用代码" min-width="180" />
|
||||
<el-table-column label="合作状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)" disable-transitions>{{ row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建日期" width="120" align="center">
|
||||
<template #default="{ row }">{{ row.createTime ? String(row.createTime).slice(0,10) : '' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="contactName" label="联系人" width="100" align="center" />
|
||||
<el-table-column prop="contactPhone" label="联系电话" width="130" align="center" />
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="view(row)">查看</el-button>
|
||||
<el-button link type="primary" @click="goPeople(row)">人员管理</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pager">
|
||||
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="detailOpen" title="服务机构详情" width="640px" v-if="currentRow">
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item label="公司类型">
|
||||
<el-tag type="primary">执行方</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="公司名称">{{ currentRow.orgName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="公司地址">{{ currentRow.address }}</el-descriptions-item>
|
||||
<el-descriptions-item label="税号/统一社会信用代码">{{ currentRow.taxNo }}</el-descriptions-item>
|
||||
<el-descriptions-item label="合作状态">
|
||||
<el-tag :type="statusTagType(currentRow.status)">{{ currentRow.status }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建日期">{{ currentRow.createTime ? String(currentRow.createTime).slice(0,10) : '' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系人">{{ currentRow.contactName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系电话">{{ currentRow.contactPhone || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<template #footer>
|
||||
<el-button @click="detailOpen=false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { bizList } from '@/api/public'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const q = ref({ orgType: 'executor', orgName: '', taxNo: '', status: '' })
|
||||
const rows = ref([])
|
||||
const loading = ref(false)
|
||||
const page = reactive({ pageNum: 1, pageSize: 10, total: 0 })
|
||||
const currentRow = ref(null)
|
||||
const detailOpen = ref(false)
|
||||
|
||||
function statusTagType(s) {
|
||||
if (s === '正常' || s === '0' || s === '合作中') return 'success'
|
||||
if (s === '禁用' || s === '1') return 'danger'
|
||||
return 'info'
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const { data } = await bizList('org', { ...q.value, pageNum: page.pageNum, pageSize: page.pageSize })
|
||||
rows.value = data?.rows || []; page.total = data?.total || 0
|
||||
} catch { rows.value = []; page.total = 0 }
|
||||
finally { loading.value = false }
|
||||
}
|
||||
function reset() { q.value = { orgType: 'executor', orgName: '', taxNo: '', status: '' }; page.pageNum = 1; load() }
|
||||
function view(row) { currentRow.value = row; detailOpen.value = true }
|
||||
function goPeople(row) {
|
||||
router.push({ path: '/manager/executor-people', query: { orgId: row.orgId, orgName: row.orgName } })
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.manager-executor-orgs { padding: 16px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
</style>
|
||||
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<!--
|
||||
角色: 🟨 合规 服务机构下人员 (manager/executor-people)
|
||||
入口: org 表格行内「人员管理」按钮 (router.push 带 orgId/orgName)
|
||||
接口: bizList('person', q) / bizUpdate / bizAdd / executorImport / executorImportTemplate
|
||||
-->
|
||||
<div class="page-card manager-executor-people">
|
||||
<div class="breadcrumb">
|
||||
首页 / 服务机构管理 / 人员管理{{ orgName ? ' (' + orgName + ')' : '' }}
|
||||
</div>
|
||||
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="q.name" placeholder="姓名" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="q.phone" placeholder="手机号" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="企业名称">
|
||||
<el-input v-model="q.orgName" placeholder="企业名称" clearable style="width:180px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门">
|
||||
<el-input v-model="q.department" placeholder="部门" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="职务">
|
||||
<el-input v-model="q.position" placeholder="职务" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="batch-bar">
|
||||
<el-button type="primary" @click="goNew">新建人员</el-button>
|
||||
<el-button @click="openImport">批量导入</el-button>
|
||||
<span class="filter-tip">*批量导入模板与列表表项一致</span>
|
||||
</div>
|
||||
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column prop="name" label="姓名" min-width="100" />
|
||||
<el-table-column prop="phone" label="手机号" min-width="130" />
|
||||
<el-table-column prop="orgName" label="企业名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="department" label="部门" min-width="100" />
|
||||
<el-table-column prop="position" label="职务" min-width="100" />
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)" disable-transitions>{{ row.status || '正常' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link :type="isDisabled(row) ? 'success' : 'danger'" @click="onToggleStatus(row)">
|
||||
{{ isDisabled(row) ? '启用' : '禁用' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
v-model:current-page="page.pageNum"
|
||||
v-model:page-size="page.pageSize"
|
||||
:total="page.total"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@current-change="load"
|
||||
@size-change="load"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="importOpen" title="批量导入" width="520px" :close-on-click-modal="false">
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="选择文件">
|
||||
<el-upload ref="uploadRef" :auto-upload="false" :limit="1" accept=".xls,.xlsx" :on-change="onFileChange" :on-remove="onFileRemove">
|
||||
<el-button>选择文件</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="">
|
||||
<el-button link type="primary" @click="downloadTemplate">批量导入模板下载</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item><span class="filter-tip">*导入列: 姓名/手机号/所属公司/部门/职务/角色</span></el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="importOpen = false">取消</el-button>
|
||||
<el-button type="primary" :loading="importing" @click="submitImport">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { bizList, bizUpdate, importPerson, downloadImportTemplate } from '@/api/public'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const orgId = computed(() => route.query.orgId ? Number(route.query.orgId) : null)
|
||||
const orgName = computed(() => route.query.orgName || '')
|
||||
|
||||
const q = reactive({ name: '', phone: '', orgName: '', department: '', position: '' })
|
||||
const rows = ref([])
|
||||
const loading = ref(false)
|
||||
const page = reactive({ pageNum: 1, pageSize: 10, total: 0 })
|
||||
|
||||
function statusTagType(s) {
|
||||
if (s === '禁用' || s === '1') return 'danger'
|
||||
return 'success'
|
||||
}
|
||||
function isDisabled(row) {
|
||||
return row.status === '禁用' || row.status === '1'
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
...q,
|
||||
orgType: 'executor',
|
||||
...(orgId.value ? { orgId: orgId.value } : {}),
|
||||
pageNum: page.pageNum,
|
||||
pageSize: page.pageSize,
|
||||
}
|
||||
const { data } = await bizList('person', params)
|
||||
rows.value = (data && data.rows) || []
|
||||
page.total = (data && data.total) || 0
|
||||
} catch { rows.value = []; page.total = 0 }
|
||||
finally { loading.value = false }
|
||||
}
|
||||
function reset() {
|
||||
Object.assign(q, { name: '', phone: '', orgName: '', department: '', position: '' })
|
||||
page.pageNum = 1
|
||||
load()
|
||||
}
|
||||
|
||||
async function onToggleStatus(row) {
|
||||
const disabled = isDisabled(row)
|
||||
const newStatus = disabled ? '正常' : '禁用'
|
||||
const label = disabled ? '启用' : '禁用'
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要${label}「${row.name}」吗?`,
|
||||
'确认',
|
||||
{ type: 'warning' }
|
||||
)
|
||||
} catch { return }
|
||||
try {
|
||||
await bizUpdate('person', { personId: row.personId, status: newStatus })
|
||||
ElMessage.success('已' + label)
|
||||
load()
|
||||
} catch (e) { ElMessage.error(e?.msg || '操作失败') }
|
||||
}
|
||||
|
||||
// ========== 新建人员 ==========
|
||||
function goNew() {
|
||||
router.push({
|
||||
path: '/manager/executor-people/new',
|
||||
query: {
|
||||
...(orgId.value ? { orgId: orgId.value } : {}),
|
||||
...(orgName.value ? { orgName: orgName.value } : {})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ========== 批量导入 ==========
|
||||
const importOpen = ref(false)
|
||||
const importing = ref(false)
|
||||
const uploadRef = ref()
|
||||
const importFile = ref(null)
|
||||
|
||||
function openImport() { importFile.value = null; importOpen.value = true }
|
||||
function onFileChange(file) { importFile.value = file.raw }
|
||||
function onFileRemove() { importFile.value = null }
|
||||
async function downloadTemplate() {
|
||||
try {
|
||||
const res = await downloadImportTemplate('executor')
|
||||
const blob = new Blob([res.data], { type: res.data.type || 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = '服务机构人员导入模板.xlsx'
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
} catch { ElMessage.error('模板下载失败') }
|
||||
}
|
||||
async function submitImport() {
|
||||
if (!importFile.value) { ElMessage.warning('请先选择文件'); return }
|
||||
importing.value = true
|
||||
try {
|
||||
const res = await importPerson('executor', importFile.value)
|
||||
const payload = res.data || res
|
||||
const ok = payload.ok ?? 0
|
||||
const total = payload.total ?? 0
|
||||
const failed = (payload.results || []).filter(r => !r.ok)
|
||||
if (failed.length === 0) {
|
||||
ElMessage.success(`导入成功 ${ok}/${total}`)
|
||||
} else {
|
||||
ElMessageBox.alert(
|
||||
`成功 ${ok} 条, 失败 ${failed.length} 条:\n` +
|
||||
failed.map(f => ` 第${f.rowNo}行 ${f.name || ''}: ${f.message}`).join('\n'),
|
||||
'导入结果', { type: 'warning' }
|
||||
)
|
||||
}
|
||||
importOpen.value = false
|
||||
load()
|
||||
} catch (e) {
|
||||
ElMessage.error(e?.msg || '导入失败')
|
||||
} finally {
|
||||
importing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.manager-executor-people { padding: 16px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.batch-bar { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; }
|
||||
.filter-tip { color: #909399; font-size: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
</style>
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="page-card">
|
||||
<div class="desc">审核专家注册信息</div>
|
||||
<div class="page-card manager-experts">
|
||||
<div class="breadcrumb">首页 / 专家审核</div>
|
||||
|
||||
<!-- ========== 筛选区 (按原型 top=174: 姓名/手机号/工作单位/审核状态) ========== -->
|
||||
<!-- ========== 筛选区 (与 People.vue 风格一致) ========== -->
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="q.name" placeholder="" clearable style="width:160px" />
|
||||
@@ -15,9 +15,10 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态">
|
||||
<el-select v-model="q.auditStatus" placeholder="请选择" clearable style="width:140px">
|
||||
<el-option label="待审核" value="0" />
|
||||
<el-option label="通过" value="1" />
|
||||
<el-option label="退回" value="2" />
|
||||
<el-option label="未提交" value="0" />
|
||||
<el-option label="待审核" value="1" />
|
||||
<el-option label="通过" value="2" />
|
||||
<el-option label="拒绝" value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
@@ -25,10 +26,8 @@
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- ========== 批量按钮区 (按原型 top=226: 新建专家/批量导入/批量审核/批量导入执业证书/批量导入职称证明) ========== -->
|
||||
<div class="page-card">
|
||||
<!-- ========== 批量按钮区 (与 People.vue 风格一致) ========== -->
|
||||
<div class="batch-bar">
|
||||
<el-button type="primary" @click="openAdd">新建专家</el-button>
|
||||
<el-button @click="openImport">批量导入</el-button>
|
||||
@@ -65,7 +64,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<span :class="['stage-tag', auditStatusClass(row.auditStatus)]">{{ auditStatusText(row.auditStatus) }}</span>
|
||||
<audit-status-tag :status="row.auditStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="auditTime" label="审批时间" width="160" align="center">
|
||||
@@ -77,16 +76,18 @@
|
||||
<el-button link type="primary" @click="onAudit(row)">审核</el-button>
|
||||
<el-button link type="primary" @click="onEdit(row)">修改</el-button>
|
||||
<el-button link type="primary" @click="onView(row)">查看</el-button>
|
||||
<el-button link :type="row.status === '1' ? 'danger' : 'success'" @click="row.status === '1' ? onDisable(row) : onEnable(row)">
|
||||
{{ row.status === '1' ? '禁用' : '恢复' }}
|
||||
<el-button link :type="row.status === 'N' ? 'success' : 'danger'" @click="row.status === 'N' ? onEnable(row) : onDisable(row)">
|
||||
{{ row.status === 'N' ? '恢复' : '禁用' }}
|
||||
</el-button>
|
||||
<el-button link type="info" v-if="row.auditStatus === '2'" @click="onViewAuditOpinion(row)">已退回</el-button>
|
||||
<el-button link type="info" v-if="row.auditStatus === '3'" @click="onViewAuditOpinion(row)">已拒绝</el-button>
|
||||
<el-button link type="primary" v-if="row.practiceCertUrl || row.titleCertUrl || row.resumeUrl" @click="onDownloadAll(row)">下载</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
|
||||
<div class="pager">
|
||||
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== Dialog: 新建/编辑专家 (按原型 top=239 确定/取消) ========== -->
|
||||
@@ -121,8 +122,8 @@
|
||||
<el-form :model="auditForm" label-width="100px">
|
||||
<el-form-item label="审核结果">
|
||||
<el-radio-group v-model="auditForm.result">
|
||||
<el-radio value="1">通过</el-radio>
|
||||
<el-radio value="2">退回</el-radio>
|
||||
<el-radio value="2">通过</el-radio>
|
||||
<el-radio value="3">拒绝</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核意见">
|
||||
@@ -144,8 +145,8 @@
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="审核结果">
|
||||
<el-radio-group v-model="importAuditResult">
|
||||
<el-radio value="1">通过</el-radio>
|
||||
<el-radio value="2">退回</el-radio>
|
||||
<el-radio value="2">通过</el-radio>
|
||||
<el-radio value="3">拒绝</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核意见">
|
||||
@@ -190,7 +191,7 @@
|
||||
<el-descriptions-item label="工作单位">{{ currentRow.workUnit }}</el-descriptions-item>
|
||||
<el-descriptions-item label="科室">{{ currentRow.department }}</el-descriptions-item>
|
||||
<el-descriptions-item label="职称">{{ currentRow.title }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核状态">{{ auditStatusText(currentRow.auditStatus) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核状态"><audit-status-tag :status="currentRow.auditStatus" /></el-descriptions-item>
|
||||
<el-descriptions-item label="执业证书">
|
||||
<el-link v-if="currentRow.practiceCertUrl" type="primary" @click="onViewCert(currentRow.practiceCertUrl)">查看证书</el-link>
|
||||
<span v-else>-</span>
|
||||
@@ -208,6 +209,7 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { bizList, bizAdd, bizUpdate } from '@/api/public'
|
||||
import AuditStatusTag from '@/components/AuditStatusTag.vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const q = ref({ name: '', phone: '', workUnit: '', auditStatus: '' })
|
||||
@@ -233,17 +235,7 @@ function reset() {
|
||||
}
|
||||
function onSel(rs) { selection.value = rs }
|
||||
|
||||
// ========== 工具: 审核状态显示/颜色 ==========
|
||||
function auditStatusText(s) {
|
||||
if (s === '1') return '通过'
|
||||
if (s === '2') return '退回'
|
||||
return '待审核'
|
||||
}
|
||||
function auditStatusClass(s) {
|
||||
if (s === '1') return 'stage-done'
|
||||
if (s === '2') return 'stage-reject'
|
||||
return 'stage-reviewing'
|
||||
}
|
||||
// auditStatusText / auditStatusClass 已删除: 改用 AuditStatusTag 组件
|
||||
function fmtTime(d) {
|
||||
if (!d) return ''
|
||||
const dt = new Date(d)
|
||||
@@ -285,7 +277,7 @@ async function submitEdit() {
|
||||
await bizUpdate('expert', { ...editForm })
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
await bizAdd('expert', { ...editForm, auditStatus: '1', auditBy: 'admin', auditTime: new Date().toISOString().slice(0, 19).replace('T', ' ') })
|
||||
await bizAdd('expert', { ...editForm, auditStatus: '2', auditBy: 'admin', auditTime: new Date().toISOString().slice(0, 19).replace('T', ' ') })
|
||||
ElMessage.success('新建成功')
|
||||
}
|
||||
editOpen.value = false
|
||||
@@ -296,12 +288,13 @@ async function submitEdit() {
|
||||
|
||||
// ========== 审核 dialog ==========
|
||||
const auditOpen = ref(false)
|
||||
const auditForm = reactive({ expertId: '', name: '', phone: '', result: '1', opinion: '' })
|
||||
// result: '2'=通过, '3'=拒绝 (BizAuditStatusEnum: 0未提交 1待审核 2通过 3拒绝)
|
||||
const auditForm = reactive({ expertId: '', name: '', phone: '', result: '2', opinion: '' })
|
||||
function onAudit(row) {
|
||||
auditForm.expertId = row.expertId
|
||||
auditForm.name = row.name
|
||||
auditForm.phone = row.phone
|
||||
auditForm.result = '1'
|
||||
auditForm.result = '2'
|
||||
auditForm.opinion = ''
|
||||
auditOpen.value = true
|
||||
}
|
||||
@@ -315,7 +308,7 @@ async function submitAudit() {
|
||||
auditBy: 'admin', // 后端应取登录用户
|
||||
auditTime: new Date().toISOString().slice(0, 19).replace('T', ' ')
|
||||
})
|
||||
ElMessage.success(auditForm.result === '1' ? '审核通过' : '已退回')
|
||||
ElMessage.success(auditForm.result === '2' ? '审核通过' : '已拒绝')
|
||||
auditOpen.value = false
|
||||
load()
|
||||
} catch { ElMessage.error('审核失败') }
|
||||
@@ -329,7 +322,7 @@ async function onBatchAudit() {
|
||||
submitting.value = true
|
||||
let ok = 0
|
||||
for (const r of selection.value) {
|
||||
try { await bizUpdate('expert', { expertId: r.expertId, auditStatus: '1', auditOpinion: '批量通过', auditBy: 'admin', auditTime: new Date().toISOString().slice(0, 19).replace('T', ' ') }); ok++ } catch {}
|
||||
try { await bizUpdate('expert', { expertId: r.expertId, auditStatus: '2', auditOpinion: '批量通过', auditBy: 'admin', auditTime: new Date().toISOString().slice(0, 19).replace('T', ' ') }); ok++ } catch {}
|
||||
}
|
||||
submitting.value = false
|
||||
ElMessage.success(`批量审核通过 ${ok}/${selection.value.length} 条`)
|
||||
@@ -339,10 +332,10 @@ async function onBatchAudit() {
|
||||
|
||||
// ========== 禁用/恢复 ==========
|
||||
async function onDisable(row) {
|
||||
try { await bizUpdate('expert', { expertId: row.expertId, status: '0' }); ElMessage.success('已禁用'); load() } catch { ElMessage.error('禁用失败') }
|
||||
try { await bizUpdate('expert', { expertId: row.expertId, status: 'N' }); ElMessage.success('已禁用'); load() } catch { ElMessage.error('禁用失败') }
|
||||
}
|
||||
async function onEnable(row) {
|
||||
try { await bizUpdate('expert', { expertId: row.expertId, status: '1' }); ElMessage.success('已恢复'); load() } catch { ElMessage.error('恢复失败') }
|
||||
try { await bizUpdate('expert', { expertId: row.expertId, status: 'Y' }); ElMessage.success('已恢复'); load() } catch { ElMessage.error('恢复失败') }
|
||||
}
|
||||
|
||||
// ========== 查看详情 ==========
|
||||
@@ -350,11 +343,11 @@ const viewOpen = ref(false)
|
||||
const currentRow = ref(null)
|
||||
function onView(row) { currentRow.value = row; viewOpen.value = true }
|
||||
|
||||
// ========== 已退回: 查看退回意见 ==========
|
||||
// ========== 已拒绝: 查看拒绝意见 ==========
|
||||
function onViewAuditOpinion(row) {
|
||||
ElMessageBox.alert(
|
||||
`退回时间: ${fmtTime(row.auditTime) || '-'}\n审批人: ${row.auditBy || '-'}\n退回意见: ${row.auditOpinion || '(无)'}`,
|
||||
`专家 ${row.name} 审核已退回`,
|
||||
`拒绝时间: ${fmtTime(row.auditTime) || '-'}\n审批人: ${row.auditBy || '-'}\n拒绝意见: ${row.auditOpinion || '(无)'}`,
|
||||
`专家 ${row.name} 审核已拒绝`,
|
||||
{ type: 'warning', confirmButtonText: '知道了' }
|
||||
).catch(() => {})
|
||||
}
|
||||
@@ -382,12 +375,12 @@ function onDownloadAll(row) {
|
||||
|
||||
// ========== 批量导入 dialog ==========
|
||||
const importOpen = ref(false)
|
||||
const importAuditResult = ref('1')
|
||||
const importAuditResult = ref('2')
|
||||
const importAuditOpinion = ref('')
|
||||
const importFileUrl = ref('')
|
||||
const importing = ref(false)
|
||||
function openImport() {
|
||||
importAuditResult.value = '1'
|
||||
importAuditResult.value = '2'
|
||||
importAuditOpinion.value = ''
|
||||
importFileUrl.value = ''
|
||||
importOpen.value = true
|
||||
@@ -400,7 +393,7 @@ async function submitImport() {
|
||||
importing.value = true
|
||||
await new Promise(r => setTimeout(r, 500))
|
||||
importing.value = false
|
||||
ElMessage.info(`已提交批量导入任务 (审核结果: ${importAuditResult.value === '1' ? '通过' : '退回'}) — 待后端实现`)
|
||||
ElMessage.info(`已提交批量导入任务 (审核结果: ${importAuditResult.value === '2' ? '通过' : '拒绝'}) — 待后端实现`)
|
||||
importOpen.value = false
|
||||
}
|
||||
|
||||
@@ -434,13 +427,12 @@ onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-card { background: #fff; border: 1px solid #ebeef5; border-radius: 6px; padding: 16px; margin-bottom: 12px; }
|
||||
.desc { color: #606266; font-size: 13px; margin-bottom: 12px; }
|
||||
.filter-form .el-form-item { margin-right: 12px; margin-bottom: 8px; }
|
||||
.batch-bar { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-experts { padding: 16px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.batch-bar { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; flex-wrap: wrap; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
|
||||
.stage-tag { display: inline-block; padding: 2px 10px; border-radius: 3px; font-size: 12px; border: 1px solid; }
|
||||
.stage-done { color: #67c23a; border-color: #c2e7b0; background: #f0f9eb; }
|
||||
.stage-reviewing { color: #e6a23c; border-color: #f5dab1; background: #fdf6ec; }
|
||||
.stage-reject { color: #f56c6c; border-color: #fbc4c4; background: #fef0f0; }
|
||||
/* stage-* CSS 已删除: 改用 AuditStatusTag 组件 (el-tag 自带颜色) */
|
||||
</style>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="page-card manager-meeting-new">
|
||||
<h2 style="margin-bottom:16px">新建会议</h2>
|
||||
<div class="breadcrumb">首页 / 会议管理 / 新建会议</div>
|
||||
<p class="page-sub" v-if="preselectProjectId">已选择项目: {{ preselectProjectId }}</p>
|
||||
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" style="max-width:700px">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="meeting-form">
|
||||
<el-form-item label="项目编号" prop="projectNo">
|
||||
<el-input v-model="form.projectNo" :disabled="!!preselectProjectId" placeholder="项目编号" />
|
||||
</el-form-item>
|
||||
@@ -100,13 +100,16 @@ onMounted(async () => {
|
||||
if (preselectProjectId) {
|
||||
try {
|
||||
const r = await bizGet('project', preselectProjectId)
|
||||
form.projectNo = r.data?.projectNo || ''
|
||||
form.projectNo = (r.data && r.data.projectNo) || ''
|
||||
} catch (e) {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-meeting-new { padding: 16px; }
|
||||
.page-sub { color: #909399; font-size: 13px; margin-bottom: 12px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.page-sub { color: #909399; font-size: 13px; margin-bottom: 16px; }
|
||||
.meeting-form { max-width: 700px; }
|
||||
</style>
|
||||
@@ -1,89 +1,80 @@
|
||||
<template>
|
||||
<div class="manager-meetings">
|
||||
<!-- ========== 筛选区 (严格按 manager 角色原型 会议管理_1.html — 第一行 6 项 + 第二行 3 项) ========== -->
|
||||
<div class="page-card">
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="项目编号">
|
||||
<el-input v-model="q.projectNo" placeholder="" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="会议ID">
|
||||
<el-input v-model="q.meetingId" placeholder="" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="会议名称">
|
||||
<el-input v-model="q.meetingName" placeholder="" clearable style="width:160px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="第?期">
|
||||
<el-input v-model="q.periodNo" placeholder="" clearable style="width:80px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="会议时间">
|
||||
<el-date-picker v-model="q.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width:170px" />
|
||||
<span style="margin:0 4px">至</span>
|
||||
<el-date-picker v-model="q.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width:170px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目形式">
|
||||
<el-select v-model="q.projectForm" placeholder="请选择" clearable style="width:140px">
|
||||
<el-option label="线上" value="线上" />
|
||||
<el-option label="线下" value="线下" />
|
||||
<el-option label="线上+线下" value="线上+线下" />
|
||||
<el-option label="其他" value="其他" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="当前阶段">
|
||||
<el-select v-model="q.currentStage" placeholder="请选择" clearable style="width:140px">
|
||||
<el-option label="未执行" value="未执行" />
|
||||
<el-option label="执行中" value="执行中" />
|
||||
<el-option label="已执行" value="已执行" />
|
||||
<el-option label="已完结" value="已完结" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="q.remark" placeholder="" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="page-card manager-meetings">
|
||||
<div class="breadcrumb">首页 / 会议管理</div>
|
||||
|
||||
<!-- ========== 筛选区 (与 People.vue 风格一致) ========== -->
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="项目编号"><el-input v-model="q.projectNo" placeholder="" clearable style="width:140px" /></el-form-item>
|
||||
<el-form-item label="会议ID"><el-input v-model="q.meetingId" placeholder="" clearable style="width:140px" /></el-form-item>
|
||||
<el-form-item label="会议名称"><el-input v-model="q.meetingName" placeholder="" clearable style="width:160px" /></el-form-item>
|
||||
<el-form-item label="第?期"><el-input v-model="q.periodNo" placeholder="" clearable style="width:80px" /></el-form-item>
|
||||
<el-form-item label="会议时间">
|
||||
<el-date-picker v-model="q.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width:170px" />
|
||||
<span style="margin:0 4px">至</span>
|
||||
<el-date-picker v-model="q.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width:170px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目形式">
|
||||
<el-select v-model="q.projectForm" placeholder="请选择" clearable style="width:140px">
|
||||
<el-option label="线上" value="线上" />
|
||||
<el-option label="线下" value="线下" />
|
||||
<el-option label="线上+线下" value="线上+线下" />
|
||||
<el-option label="其他" value="其他" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="当前阶段">
|
||||
<el-select v-model="q.currentStage" placeholder="请选择" clearable style="width:140px">
|
||||
<el-option label="未执行" value="未执行" />
|
||||
<el-option label="执行中" value="执行中" />
|
||||
<el-option label="已执行" value="已执行" />
|
||||
<el-option label="已完结" value="已完结" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="q.remark" placeholder="" clearable style="width:140px" /></el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- ========== 批量提交按钮 (manager 角色专有) ========== -->
|
||||
<div class="batch-bar">
|
||||
<el-button type="primary" plain :disabled="!selectedIds.length" @click="onBatchSubmit">批量提交</el-button>
|
||||
<span v-if="selectedIds.length" class="filter-tip">已选 {{ selectedIds.length }} 条</span>
|
||||
</div>
|
||||
|
||||
<!-- ========== 表格区 (按 manager 角色原型 会议管理_1.html: 操作列 4 按钮 — 查看/修改/提交/复制) ========== -->
|
||||
<div class="page-card">
|
||||
<!-- 批量提交按钮 (manager 角色才有) -->
|
||||
<div class="batch-bar" v-if="selectedIds.length">
|
||||
<el-button type="primary" plain @click="onBatchSubmit" :disabled="!selectedIds.length">批量提交</el-button>
|
||||
<span class="selected-tip">已选 {{ selectedIds.length }} 条</span>
|
||||
</div>
|
||||
<el-table :data="rows" v-loading="loading" stripe border @selection-change="onSelectionChange">
|
||||
<el-table-column type="selection" width="44" />
|
||||
<el-table-column prop="projectNo" label="项目编号" width="130" fixed />
|
||||
<el-table-column prop="meetingId" label="会议ID" width="120" align="center" />
|
||||
<el-table-column prop="projectForm" label="项目形式" width="100" align="center" />
|
||||
<el-table-column prop="meetingName" label="会议名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="会议开始时间" width="160" align="center">
|
||||
<template #default="{ row }">{{ fmtTime(row.startTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会议结束时间" width="160" align="center">
|
||||
<template #default="{ row }">{{ fmtTime(row.endTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalPeriods" label="总期数" width="80" align="center" />
|
||||
<el-table-column label="期数" width="80" align="center">
|
||||
<template #default="{ row }">第 {{ row.periodNo || 0 }} 期</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="currentStage" label="当前阶段" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<span :class="['stage-tag', 'stage-' + stageClass(row.currentStage)]">{{ row.currentStage }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="240" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="onView(row)">查看</el-button>
|
||||
<el-button link type="primary" @click="onEdit(row)">修改</el-button>
|
||||
<el-button link type="primary" @click="onSubmit(row)">提交</el-button>
|
||||
<el-button link type="primary" @click="onCopy(row)">复制</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- ========== 表格 (与 People.vue 风格一致, 无 page-card 包裹) ========== -->
|
||||
<el-table :data="rows" v-loading="loading" stripe border @selection-change="onSelectionChange">
|
||||
<el-table-column type="selection" width="44" />
|
||||
<el-table-column prop="projectNo" label="项目编号" width="130" fixed />
|
||||
<el-table-column prop="meetingId" label="会议ID" width="120" align="center" />
|
||||
<el-table-column prop="projectForm" label="项目形式" width="100" align="center" />
|
||||
<el-table-column prop="meetingName" label="会议名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="会议开始时间" width="160" align="center">
|
||||
<template #default="{ row }">{{ fmtTime(row.startTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会议结束时间" width="160" align="center">
|
||||
<template #default="{ row }">{{ fmtTime(row.endTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalPeriods" label="总期数" width="80" align="center" />
|
||||
<el-table-column label="期数" width="80" align="center">
|
||||
<template #default="{ row }">第 {{ row.periodNo || 0 }} 期</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="currentStage" label="当前阶段" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<span :class="['stage-tag', 'stage-' + stageClass(row.currentStage)]">{{ row.currentStage }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="240" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="onView(row)">查看</el-button>
|
||||
<el-button link type="primary" @click="onEdit(row)">修改</el-button>
|
||||
<el-button link type="primary" @click="onSubmit(row)">提交</el-button>
|
||||
<el-button link type="primary" @click="onCopy(row)">复制</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
v-model:current-page="page.pageNum"
|
||||
v-model:page-size="page.pageSize"
|
||||
@@ -289,19 +280,15 @@ onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-meetings { padding: 16px; }
|
||||
.page-card {
|
||||
background: #fff;
|
||||
border-radius: 6px;
|
||||
padding: 16px;
|
||||
border: 1px solid #ebeef5;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.filter-form .el-form-item { margin-right: 12px; margin-bottom: 12px; }
|
||||
.batch-bar { margin-bottom: 12px; display: flex; align-items: center; gap: 8px; }
|
||||
.batch-bar .selected-tip { color: #909399; font-size: 13px; margin-left: 8px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.batch-bar { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; }
|
||||
.filter-tip { color: #909399; font-size: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
|
||||
/* 当前阶段 tag 颜色 */
|
||||
/* 当前阶段 tag 颜色 (业务专用, 其它页没有) */
|
||||
.stage-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
@@ -309,11 +296,11 @@ onMounted(load)
|
||||
font-size: 12px;
|
||||
border: 1px solid;
|
||||
}
|
||||
.stage-pending { color: #909399; border-color: #dcdfe6; background: #f5f7fa; }
|
||||
.stage-running { color: #409eff; border-color: #b3d8ff; background: #ecf5ff; }
|
||||
.stage-done { color: #67c23a; border-color: #c2e7b0; background: #f0f9eb; }
|
||||
.stage-pending { color: #909399; border-color: #dcdfe6; background: #f5f7fa; }
|
||||
.stage-running { color: var(--brand-primary); border-color: #b3c5e0; background: #eef1f8; }
|
||||
.stage-done { color: #67c23a; border-color: #c2e7b0; background: #f0f9eb; }
|
||||
.stage-reviewing { color: #e6a23c; border-color: #f5dab1; background: #fdf6ec; }
|
||||
.stage-waiting { color: #f56c6c; border-color: #fbc4c4; background: #fef0f0; }
|
||||
.stage-frozen { color: #909399; border-color: #dcdfe6; background: #f5f7fa; opacity: 0.6; }
|
||||
.stage-default { color: #606266; border-color: #dcdfe6; background: #fafafa; }
|
||||
.stage-waiting { color: #ff4d4f; border-color: #fbc4c4; background: #fef0f0; }
|
||||
.stage-frozen { color: #909399; border-color: #dcdfe6; background: #f5f7fa; opacity: 0.6; }
|
||||
.stage-default { color: #606266; border-color: #dcdfe6; background: #fafafa; }
|
||||
</style>
|
||||
@@ -4,69 +4,66 @@
|
||||
重构说明: 原 manager/SupportUnits.vue (仅看支持单位) 改为可看所有公司
|
||||
接口: bizList('org', q) / bizUpdate
|
||||
-->
|
||||
<div class="manager-orgs">
|
||||
<div class="page-card">
|
||||
<div class="page-title">公司查看</div>
|
||||
<div class="desc">公司管理 > 公司查看 (赞助方 + 执行方)</div>
|
||||
<el-form inline :model="q">
|
||||
<el-form-item label="公司类型:">
|
||||
<el-select v-model="q.orgType" placeholder="全部" clearable style="width:140px">
|
||||
<el-option label="赞助方" value="sponsor" />
|
||||
<el-option label="执行方" value="executor" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="公司名称:">
|
||||
<el-input v-model="q.orgName" placeholder="输入公司名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="税号/统一社会信用代码:">
|
||||
<el-input v-model="q.taxNo" placeholder="输入税号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="合作状态:">
|
||||
<el-select v-model="q.status" placeholder="请选择" clearable>
|
||||
<el-option label="正常/合作中" value="0" />
|
||||
<el-option label="合作中" value="合作中" />
|
||||
<el-option label="禁用" value="禁用" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="action-btn" @click="load">查找</el-button>
|
||||
<el-button class="action-btn secondary" @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="page-card manager-orgs">
|
||||
<div class="breadcrumb">首页 / 公司管理</div>
|
||||
|
||||
<div class="page-card">
|
||||
<div class="page-toolbar">
|
||||
<el-button class="action-btn secondary" @click="goBack">返回</el-button>
|
||||
</div>
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column label="类型" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.orgType === 'sponsor' ? 'success' : 'primary'" disable-transitions>
|
||||
{{ row.orgType === 'sponsor' ? '赞助方' : '执行方' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="orgName" label="公司名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="address" label="公司地址" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column prop="taxNo" label="税号/统一社会信用代码" min-width="180" />
|
||||
<el-table-column label="合作状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)" disable-transitions>{{ row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建日期" width="120" align="center">
|
||||
<template #default="{ row }">{{ row.createTime ? String(row.createTime).slice(0,10) : '' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="contactName" label="联系人" width="100" align="center" />
|
||||
<el-table-column prop="contactPhone" label="联系电话" width="130" align="center" />
|
||||
<el-table-column label="操作" width="160" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="view(row)">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- ========== 筛选区 (与 People.vue 风格一致) ========== -->
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="公司类型">
|
||||
<el-select v-model="q.orgType" placeholder="全部" clearable style="width:140px">
|
||||
<el-option label="赞助方" value="sponsor" />
|
||||
<el-option label="执行方" value="executor" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="公司名称">
|
||||
<el-input v-model="q.orgName" placeholder="输入公司名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="税号/统一社会信用代码">
|
||||
<el-input v-model="q.taxNo" placeholder="输入税号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="合作状态">
|
||||
<el-select v-model="q.status" placeholder="请选择" clearable>
|
||||
<el-option label="正常/合作中" value="0" />
|
||||
<el-option label="合作中" value="合作中" />
|
||||
<el-option label="禁用" value="禁用" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- ========== 表格 (与 People.vue 风格一致, 无 page-card 包裹) ========== -->
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column label="类型" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.orgType === 'sponsor' ? 'success' : 'primary'" disable-transitions>
|
||||
{{ row.orgType === 'sponsor' ? '赞助方' : '执行方' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="orgName" label="公司名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="address" label="公司地址" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column prop="taxNo" label="税号/统一社会信用代码" min-width="180" />
|
||||
<el-table-column label="合作状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)" disable-transitions>{{ row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建日期" width="120" align="center">
|
||||
<template #default="{ row }">{{ row.createTime ? String(row.createTime).slice(0,10) : '' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="contactName" label="联系人" width="100" align="center" />
|
||||
<el-table-column prop="contactPhone" label="联系电话" width="130" align="center" />
|
||||
<el-table-column label="操作" width="160" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="view(row)">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pager">
|
||||
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
|
||||
</div>
|
||||
|
||||
@@ -129,20 +126,9 @@ onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-orgs { padding: 16px; }
|
||||
.page-card { background: #fff; border-radius: 6px; padding: 16px; border: 1px solid #ebeef5; margin-bottom: 12px; }
|
||||
.page-title { font-size: 20px; font-weight: 600; margin-bottom: 4px; padding-left: 10px; border-left: 3px solid var(--brand-primary); }
|
||||
.desc { color: #909399; font-size: 13px; margin-bottom: 12px; }
|
||||
.page-toolbar { display: flex; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; align-items: center; }
|
||||
.page-toolbar :deep(.action-btn) {
|
||||
height: 36px; padding: 0 20px; font-size: 14px; border-radius: 4px;
|
||||
background: var(--brand-primary); color: #fff; border: 1px solid var(--brand-primary);
|
||||
display: inline-flex; align-items: center; justify-content: center; white-space: nowrap;
|
||||
transition: opacity .15s; margin-left: 0;
|
||||
}
|
||||
.page-toolbar :deep(.action-btn:hover) { opacity: .85; }
|
||||
.page-toolbar :deep(.action-btn.secondary) {
|
||||
background: #fff; color: var(--brand-primary); border: 1px solid var(--brand-primary);
|
||||
}
|
||||
.page-toolbar :deep(.action-btn.secondary:hover) { background: rgba(30,58,138,.06); }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
</style>
|
||||
|
||||
+112
-112
@@ -1,95 +1,92 @@
|
||||
<template>
|
||||
<div class="manager-plans">
|
||||
<div class="page-card">
|
||||
<div class="page-title">项目策划方案管理</div>
|
||||
<div class="desc">审核 / 修改 / 结算 项目策划方案</div>
|
||||
<el-form inline :model="q">
|
||||
<!-- 按原型 top=171-178 的筛选区: 项目编号(52) / 项目编号(141) / 策划方案名称(254) / 项目方向(519) / 策划方案名称(591) / 状态(939) / 备注(1138) / 备注(1177) -->
|
||||
<el-form-item label="项目编号:"><el-input v-model="q.projectNo" placeholder="输入项目编号" clearable /></el-form-item>
|
||||
<el-form-item label="策划方案名称:"><el-input v-model="q.planName" placeholder="输入策划方案名称" clearable /></el-form-item>
|
||||
<el-form-item label="项目方向:">
|
||||
<el-select v-model="q.planDirection" placeholder="请选择" clearable>
|
||||
<el-option label="专项计划一" value="专项计划一" /><el-option label="专项计划二" value="专项计划二" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="项目类别:">
|
||||
<el-select v-model="q.planCategory" placeholder="请选择" clearable>
|
||||
<el-option label="共识" value="共识" /><el-option label="对外交流" value="对外交流" />
|
||||
<el-option label="学术项目" value="学术项目" /><el-option label="科研项目" value="科研项目" />
|
||||
<el-option label="指南" value="指南" /><el-option label="会议项目" value="会议项目" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态:">
|
||||
<el-select v-model="q.status" placeholder="请选择" clearable>
|
||||
<el-option label="待审核" value="0" /><el-option label="审核通过" value="1" /><el-option label="已退回" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否结算:">
|
||||
<el-select v-model="q.isSettled" placeholder="请选择" clearable>
|
||||
<el-option label="已结算" value="1" /><el-option label="未结算" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注:"><el-input v-model="q.remark" placeholder="输入备注" clearable /></el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="action-btn" @click="load">查找</el-button>
|
||||
<el-button class="action-btn secondary" @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="filter-tip">*批量审核:策划案名称,投稿ID,审核结果,审核意见,只能审核不通过</div>
|
||||
<div class="page-card manager-plans">
|
||||
<div class="breadcrumb">首页 / 项目策划方案</div>
|
||||
<div class="hint-list">
|
||||
<p>*批量审核:策划案名称,投稿ID,审核结果,审核意见,只能审核不通过</p>
|
||||
</div>
|
||||
|
||||
<div class="page-card">
|
||||
<!-- 批量按钮 (按原型 left: 批量审核 266 / 批量结算 432) -->
|
||||
<div class="page-toolbar">
|
||||
<el-button class="action-btn" :disabled="!selection.length" @click="batchAudit">
|
||||
批量审核<span v-if="selection.length" class="badge">{{ selection.length }}</span>
|
||||
</el-button>
|
||||
<el-button class="action-btn secondary" :disabled="!selection.length" @click="batchSettle">
|
||||
批量结算<span v-if="selection.length" class="badge">{{ selection.length }}</span>
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- 列头顺序严格按原型 top=294-300 的 left: 策划方案名称 342 / 项目方向 569 / 项目类别 739 / 项目形式 864 / 设计文件 999 / 状态 1133 / 是否结算 1246 / 项目编号 1348 / 备注 1492 / 操作 1640 -->
|
||||
<el-table :data="rows" v-loading="loading" stripe border @selection-change="onSel">
|
||||
<el-table-column type="selection" width="44" />
|
||||
<el-table-column prop="planName" label="策划方案名称" min-width="200" fixed show-overflow-tooltip />
|
||||
<el-table-column prop="planDirection" label="项目方向" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column prop="planCategory" label="项目类别" width="100" align="center" />
|
||||
<el-table-column prop="projectForm" label="项目形式" width="100" align="center" />
|
||||
<el-table-column label="设计文件" width="160" align="center">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.designFileUrl">
|
||||
<el-button link type="primary" @click="onFile(row)">查看</el-button>
|
||||
<el-button link type="primary" @click="downloadFile(row)">下载</el-button>
|
||||
</template>
|
||||
<span v-else style="color:#c0c4cc">-</span>
|
||||
<!-- ========== 筛选区 (与 People.vue 风格一致) ========== -->
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="项目编号"><el-input v-model="q.projectNo" placeholder="输入项目编号" clearable /></el-form-item>
|
||||
<el-form-item label="策划方案名称"><el-input v-model="q.planName" placeholder="输入策划方案名称" clearable /></el-form-item>
|
||||
<el-form-item label="项目方向">
|
||||
<el-select v-model="q.planDirection" placeholder="请选择" clearable>
|
||||
<el-option label="专项计划一" value="专项计划一" /><el-option label="专项计划二" value="专项计划二" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="项目类别">
|
||||
<el-select v-model="q.planCategory" placeholder="请选择" clearable>
|
||||
<el-option label="共识" value="共识" /><el-option label="对外交流" value="对外交流" />
|
||||
<el-option label="学术项目" value="学术项目" /><el-option label="科研项目" value="科研项目" />
|
||||
<el-option label="指南" value="指南" /><el-option label="会议项目" value="会议项目" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="q.status" placeholder="请选择" clearable>
|
||||
<el-option label="待审核" value="0" /><el-option label="审核通过" value="1" /><el-option label="已退回" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否结算">
|
||||
<el-select v-model="q.isSettled" placeholder="请选择" clearable>
|
||||
<el-option label="已结算" value="1" /><el-option label="未结算" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="q.remark" placeholder="输入备注" clearable /></el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- ========== 批量按钮 (与 People.vue 风格一致) ========== -->
|
||||
<div class="batch-bar">
|
||||
<el-button type="primary" :disabled="!selection.length" @click="batchAudit">批量审核</el-button>
|
||||
<el-button type="primary" :disabled="!selection.length" @click="batchSettle">批量结算</el-button>
|
||||
<span v-if="selection.length" class="filter-tip">已选 {{ selection.length }} 条</span>
|
||||
</div>
|
||||
|
||||
<!-- ========== 表格 (与 People.vue 风格一致, 无 page-card 包裹) ========== -->
|
||||
<el-table :data="rows" v-loading="loading" stripe border @selection-change="onSel">
|
||||
<el-table-column type="selection" width="44" />
|
||||
<el-table-column prop="planName" label="策划方案名称" min-width="200" fixed show-overflow-tooltip />
|
||||
<el-table-column prop="planDirection" label="项目方向" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column prop="planCategory" label="项目类别" width="100" align="center" />
|
||||
<el-table-column prop="projectForm" label="项目形式" width="100" align="center" />
|
||||
<el-table-column label="设计文件" width="160" align="center">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.designFileUrl">
|
||||
<el-button link type="primary" @click="onFile(row)">查看</el-button>
|
||||
<el-button link type="primary" @click="downloadFile(row)">下载</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="small" :type="row.status==='1' ? 'success' : row.status==='2' ? 'danger' : 'warning'">
|
||||
{{ row.status==='1' ? '审核通过' : row.status==='2' ? '已退回' : '待审核' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否结算" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="small" :type="row.isSettled==='1' ? 'success' : 'warning'">
|
||||
{{ row.isSettled==='1' ? '已结算' : '未结算' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectNo" label="项目编号" width="140" align="center" />
|
||||
<el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip />
|
||||
<!-- 操作列按原型 left 顺序: 审核 1586 / 修改 1640 / 结算 1693 -->
|
||||
<el-table-column label="操作" width="240" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="onAudit(row)">审核</el-button>
|
||||
<el-button link type="primary" @click="onEdit(row)">修改</el-button>
|
||||
<el-button link type="primary" @click="onSettle(row)" v-if="row.isSettled!=='1'">结算</el-button>
|
||||
<el-button link type="primary" v-if="row.designFileUrl" @click="downloadFile(row)">下载</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<span v-else style="color:#c0c4cc">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="small" :type="row.status==='1' ? 'success' : row.status==='2' ? 'danger' : 'warning'">
|
||||
{{ row.status==='1' ? '审核通过' : row.status==='2' ? '已退回' : '待审核' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否结算" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="small" :type="row.isSettled==='1' ? 'success' : 'warning'">
|
||||
{{ row.isSettled==='1' ? '已结算' : '未结算' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectNo" label="项目编号" width="140" align="center" />
|
||||
<el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="240" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="onAudit(row)">审核</el-button>
|
||||
<el-button link type="primary" @click="onEdit(row)">修改</el-button>
|
||||
<el-button link type="primary" @click="onSettle(row)" v-if="row.isSettled!=='1'">结算</el-button>
|
||||
<el-button link type="primary" v-if="row.designFileUrl" @click="downloadFile(row)">下载</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pager">
|
||||
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
|
||||
</div>
|
||||
|
||||
@@ -282,31 +279,34 @@ onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-plans { padding: 16px; }
|
||||
.page-card { background: #fff; border-radius: 6px; padding: 16px; border: 1px solid #ebeef5; margin-bottom: 12px; }
|
||||
.page-title { font-size: 20px; font-weight: 600; margin-bottom: 4px; padding-left: 10px; border-left: 3px solid var(--brand-primary); }
|
||||
.desc { color: #909399; font-size: 13px; margin-bottom: 12px; }
|
||||
.filter-tip { color: #ff4d4f; font-size: 12px; margin-top: 8px; }
|
||||
.page-toolbar { display: flex; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; align-items: center; }
|
||||
.page-toolbar :deep(.action-btn) {
|
||||
height: 36px; padding: 0 20px; font-size: 14px; border-radius: 4px;
|
||||
background: var(--brand-primary); color: #fff; border: 1px solid var(--brand-primary);
|
||||
display: inline-flex; align-items: center; justify-content: center; white-space: nowrap;
|
||||
transition: opacity .15s; margin-left: 0;
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.page-title {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin: 0 0 6px;
|
||||
padding-left: 10px;
|
||||
border-left: 3px solid var(--brand-primary);
|
||||
}
|
||||
.page-toolbar :deep(.action-btn:hover) { opacity: .85; }
|
||||
.page-toolbar :deep(.action-btn.secondary) {
|
||||
background: #fff; color: var(--brand-primary); border: 1px solid var(--brand-primary);
|
||||
.page-sub { font-size: 13px; color: #909399; margin: 0 0 16px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.batch-bar { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; }
|
||||
.filter-tip { color: #909399; font-size: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
|
||||
/* 红字提示 (与 People.vue 一致) */
|
||||
.hint-list {
|
||||
background: #fff;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 8px;
|
||||
padding: 12px 20px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 12px;
|
||||
color: #ff4d4f;
|
||||
line-height: 1.8;
|
||||
}
|
||||
.page-toolbar :deep(.action-btn.secondary:hover) { background: rgba(30,58,138,.06); }
|
||||
.page-toolbar :deep(.action-btn.is-disabled),
|
||||
.page-toolbar :deep(.action-btn:disabled) { background: #f5f7fa; color: #c0c4cc; border-color: #e4e7ed; opacity: 1; cursor: not-allowed; }
|
||||
.page-toolbar :deep(.action-btn.secondary.is-disabled),
|
||||
.page-toolbar :deep(.action-btn.secondary:disabled) { background: #fff; color: #c0c4cc; border-color: #e4e7ed; }
|
||||
.page-toolbar :deep(.action-btn .badge) {
|
||||
display: inline-block; margin-left: 6px; padding: 0 6px; min-width: 18px; height: 18px;
|
||||
line-height: 18px; font-size: 11px; text-align: center;
|
||||
background: #fff; color: var(--brand-primary); border-radius: 9px;
|
||||
}
|
||||
.page-toolbar :deep(.action-btn.secondary .badge) { background: var(--brand-primary); color: #fff; }
|
||||
.hint-list p { margin-bottom: 4px; }
|
||||
.hint-list p:last-child { margin-bottom: 0; }
|
||||
</style>
|
||||
|
||||
@@ -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>
|
||||
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<!--
|
||||
角色: 🟨 合规 支持单位查看 (manager/sponsor-orgs)
|
||||
说明: 原 manager/Orgs.vue 拆出 sponsor 一支, 仅查看
|
||||
接口: bizList('org', q)
|
||||
-->
|
||||
<div class="page-card manager-sponsor-orgs">
|
||||
<div class="breadcrumb">首页 / 支持单位管理</div>
|
||||
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="公司名称">
|
||||
<el-input v-model="q.orgName" placeholder="输入公司名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="税号/统一社会信用代码">
|
||||
<el-input v-model="q.taxNo" placeholder="输入税号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="合作状态">
|
||||
<el-select v-model="q.status" placeholder="请选择" clearable>
|
||||
<el-option label="正常/合作中" value="0" />
|
||||
<el-option label="合作中" value="合作中" />
|
||||
<el-option label="禁用" value="禁用" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column prop="orgName" label="公司名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="address" label="公司地址" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column prop="taxNo" label="税号/统一社会信用代码" min-width="180" />
|
||||
<el-table-column label="合作状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)" disable-transitions>{{ row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建日期" width="120" align="center">
|
||||
<template #default="{ row }">{{ row.createTime ? String(row.createTime).slice(0,10) : '' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="contactName" label="联系人" width="100" align="center" />
|
||||
<el-table-column prop="contactPhone" label="联系电话" width="130" align="center" />
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="view(row)">查看</el-button>
|
||||
<el-button link type="primary" @click="goPeople(row)">人员管理</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pager">
|
||||
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="detailOpen" title="支持单位详情" width="640px" v-if="currentRow">
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item label="公司类型">
|
||||
<el-tag type="success">赞助方</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="公司名称">{{ currentRow.orgName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="公司地址">{{ currentRow.address }}</el-descriptions-item>
|
||||
<el-descriptions-item label="税号/统一社会信用代码">{{ currentRow.taxNo }}</el-descriptions-item>
|
||||
<el-descriptions-item label="合作状态">
|
||||
<el-tag :type="statusTagType(currentRow.status)">{{ currentRow.status }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建日期">{{ currentRow.createTime ? String(currentRow.createTime).slice(0,10) : '' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系人">{{ currentRow.contactName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系电话">{{ currentRow.contactPhone || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<template #footer>
|
||||
<el-button @click="detailOpen=false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { bizList } from '@/api/public'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const q = ref({ orgType: 'sponsor', orgName: '', taxNo: '', status: '' })
|
||||
const rows = ref([])
|
||||
const loading = ref(false)
|
||||
const page = reactive({ pageNum: 1, pageSize: 10, total: 0 })
|
||||
const currentRow = ref(null)
|
||||
const detailOpen = ref(false)
|
||||
|
||||
function statusTagType(s) {
|
||||
if (s === '正常' || s === '0' || s === '合作中') return 'success'
|
||||
if (s === '禁用' || s === '1') return 'danger'
|
||||
return 'info'
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const { data } = await bizList('org', { ...q.value, pageNum: page.pageNum, pageSize: page.pageSize })
|
||||
rows.value = data?.rows || []; page.total = data?.total || 0
|
||||
} catch { rows.value = []; page.total = 0 }
|
||||
finally { loading.value = false }
|
||||
}
|
||||
function reset() { q.value = { orgType: 'sponsor', orgName: '', taxNo: '', status: '' }; page.pageNum = 1; load() }
|
||||
function view(row) { currentRow.value = row; detailOpen.value = true }
|
||||
function goPeople(row) {
|
||||
router.push({ path: '/manager/sponsor-people', query: { orgId: row.orgId, orgName: row.orgName } })
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.manager-sponsor-orgs { padding: 16px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
</style>
|
||||
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<!--
|
||||
角色: 🟨 合规 支持单位下人员 (manager/sponsor-people)
|
||||
入口: org 表格行内「人员管理」按钮 (router.push 带 orgId/orgName)
|
||||
接口: bizList('person', q) / bizUpdate / bizAdd / sponsorImport / sponsorImportTemplate
|
||||
-->
|
||||
<div class="page-card manager-sponsor-people">
|
||||
<div class="breadcrumb">
|
||||
首页 / 支持单位管理 / 人员管理{{ orgName ? ' (' + orgName + ')' : '' }}
|
||||
</div>
|
||||
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="q.name" placeholder="姓名" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="q.phone" placeholder="手机号" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="企业名称">
|
||||
<el-input v-model="q.orgName" placeholder="企业名称" clearable style="width:180px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门">
|
||||
<el-input v-model="q.department" placeholder="部门" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="职务">
|
||||
<el-input v-model="q.position" placeholder="职务" clearable style="width:140px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="batch-bar">
|
||||
<el-button type="primary" @click="goNew">新建人员</el-button>
|
||||
<el-button @click="openImport">批量导入</el-button>
|
||||
<span class="filter-tip">*批量导入模板与列表表项一致</span>
|
||||
</div>
|
||||
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column prop="name" label="姓名" min-width="100" />
|
||||
<el-table-column prop="phone" label="手机号" min-width="130" />
|
||||
<el-table-column prop="orgName" label="企业名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="department" label="部门" min-width="100" />
|
||||
<el-table-column prop="position" label="职务" min-width="100" />
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)" disable-transitions>{{ row.status || '正常' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link :type="isDisabled(row) ? 'success' : 'danger'" @click="onToggleStatus(row)">
|
||||
{{ isDisabled(row) ? '启用' : '禁用' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
v-model:current-page="page.pageNum"
|
||||
v-model:page-size="page.pageSize"
|
||||
:total="page.total"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@current-change="load"
|
||||
@size-change="load"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="importOpen" title="批量导入" width="520px" :close-on-click-modal="false">
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="选择文件">
|
||||
<el-upload ref="uploadRef" :auto-upload="false" :limit="1" accept=".xls,.xlsx" :on-change="onFileChange" :on-remove="onFileRemove">
|
||||
<el-button>选择文件</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="">
|
||||
<el-button link type="primary" @click="downloadTemplate">批量导入模板下载</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item><span class="filter-tip">*导入列: 姓名/手机号/所属公司/部门/职务/角色</span></el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="importOpen = false">取消</el-button>
|
||||
<el-button type="primary" :loading="importing" @click="submitImport">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { bizList, bizUpdate, importPerson, downloadImportTemplate } from '@/api/public'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const orgId = computed(() => route.query.orgId ? Number(route.query.orgId) : null)
|
||||
const orgName = computed(() => route.query.orgName || '')
|
||||
|
||||
const q = reactive({ name: '', phone: '', orgName: '', department: '', position: '' })
|
||||
const rows = ref([])
|
||||
const loading = ref(false)
|
||||
const page = reactive({ pageNum: 1, pageSize: 10, total: 0 })
|
||||
|
||||
function statusTagType(s) {
|
||||
if (s === '禁用' || s === '1') return 'danger'
|
||||
return 'success'
|
||||
}
|
||||
function isDisabled(row) {
|
||||
return row.status === '禁用' || row.status === '1'
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
...q,
|
||||
orgType: 'sponsor',
|
||||
...(orgId.value ? { orgId: orgId.value } : {}),
|
||||
pageNum: page.pageNum,
|
||||
pageSize: page.pageSize,
|
||||
}
|
||||
const { data } = await bizList('person', params)
|
||||
rows.value = (data && data.rows) || []
|
||||
page.total = (data && data.total) || 0
|
||||
} catch { rows.value = []; page.total = 0 }
|
||||
finally { loading.value = false }
|
||||
}
|
||||
function reset() {
|
||||
Object.assign(q, { name: '', phone: '', orgName: '', department: '', position: '' })
|
||||
page.pageNum = 1
|
||||
load()
|
||||
}
|
||||
|
||||
async function onToggleStatus(row) {
|
||||
const disabled = isDisabled(row)
|
||||
const newStatus = disabled ? '正常' : '禁用'
|
||||
const label = disabled ? '启用' : '禁用'
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要${label}「${row.name}」吗?`,
|
||||
'确认',
|
||||
{ type: 'warning' }
|
||||
)
|
||||
} catch { return }
|
||||
try {
|
||||
await bizUpdate('person', { personId: row.personId, status: newStatus })
|
||||
ElMessage.success('已' + label)
|
||||
load()
|
||||
} catch (e) { ElMessage.error(e?.msg || '操作失败') }
|
||||
}
|
||||
|
||||
// ========== 新建人员 ==========
|
||||
function goNew() {
|
||||
router.push({
|
||||
path: '/manager/sponsor-people/new',
|
||||
query: {
|
||||
...(orgId.value ? { orgId: orgId.value } : {}),
|
||||
...(orgName.value ? { orgName: orgName.value } : {})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ========== 批量导入 ==========
|
||||
const importOpen = ref(false)
|
||||
const importing = ref(false)
|
||||
const uploadRef = ref()
|
||||
const importFile = ref(null)
|
||||
|
||||
function openImport() { importFile.value = null; importOpen.value = true }
|
||||
function onFileChange(file) { importFile.value = file.raw }
|
||||
function onFileRemove() { importFile.value = null }
|
||||
async function downloadTemplate() {
|
||||
try {
|
||||
const res = await downloadImportTemplate('sponsor')
|
||||
const blob = new Blob([res.data], { type: res.data.type || 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = '支持单位人员导入模板.xlsx'
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
} catch { ElMessage.error('模板下载失败') }
|
||||
}
|
||||
async function submitImport() {
|
||||
if (!importFile.value) { ElMessage.warning('请先选择文件'); return }
|
||||
importing.value = true
|
||||
try {
|
||||
const res = await importPerson('sponsor', importFile.value)
|
||||
const payload = res.data || res
|
||||
const ok = payload.ok ?? 0
|
||||
const total = payload.total ?? 0
|
||||
const failed = (payload.results || []).filter(r => !r.ok)
|
||||
if (failed.length === 0) {
|
||||
ElMessage.success(`导入成功 ${ok}/${total}`)
|
||||
} else {
|
||||
ElMessageBox.alert(
|
||||
`成功 ${ok} 条, 失败 ${failed.length} 条:\n` +
|
||||
failed.map(f => ` 第${f.rowNo}行 ${f.name || ''}: ${f.message}`).join('\n'),
|
||||
'导入结果', { type: 'warning' }
|
||||
)
|
||||
}
|
||||
importOpen.value = false
|
||||
load()
|
||||
} catch (e) {
|
||||
ElMessage.error(e?.msg || '导入失败')
|
||||
} finally {
|
||||
importing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.manager-sponsor-people { padding: 16px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.batch-bar { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; }
|
||||
.filter-tip { color: #909399; font-size: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
</style>
|
||||
@@ -1,41 +1,43 @@
|
||||
<template>
|
||||
<div class="manager-support-intent">
|
||||
<div class="page-card">
|
||||
<div class="page-title">支持意向</div>
|
||||
<!-- 筛选区严格按原型 top=169-217 的 left 顺序: 意向项目名称(276) / ZH-2026-658(371) / 姓名(541) / 工作单位(580) / 工作单位(750) / 工作单位(817) / 项目编号(996) / 提示(1113) -->
|
||||
<el-form inline :model="q">
|
||||
<el-form-item label="项目编号:"><el-input v-model="q.projectNo" placeholder="如 ZH-2026-658" clearable /></el-form-item>
|
||||
<el-form-item label="意向项目名称:"><el-input v-model="q.projectName" placeholder="输入意向项目名称" clearable /></el-form-item>
|
||||
<el-form-item label="姓名:"><el-input v-model="q.name" placeholder="输入姓名" clearable /></el-form-item>
|
||||
<el-form-item label="工作单位:"><el-input v-model="q.workUnit" placeholder="输入工作单位" clearable /></el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="action-btn" @click="load">查找</el-button>
|
||||
<el-button class="action-btn secondary" @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 提示语严格按原型 top=217-243 -->
|
||||
<div class="filter-tip">*项目公示中点击支持意向后,显示在此</div>
|
||||
<div class="filter-tip">*支持意向不需要注册,但是如果已经注册账号,则显示账号状态</div>
|
||||
<div class="filter-tip">*根据手机号与系统账号进行匹配</div>
|
||||
<div class="page-card manager-support-intent">
|
||||
<div class="breadcrumb">首页 / 支持意向</div>
|
||||
|
||||
<!-- 提示语 (按原型 top=217-243) -->
|
||||
<div class="hint-list">
|
||||
<p>*项目公示中点击支持意向后,显示在此</p>
|
||||
<p>*支持意向不需要注册,但是如果已经注册账号,则显示账号状态</p>
|
||||
<p>*根据手机号与系统账号进行匹配</p>
|
||||
</div>
|
||||
|
||||
<div class="page-card">
|
||||
<!-- 列头严格按原型 top=296 left 顺序: 支持意向项目编号 272 / 支持意向项目名称 437 / 姓名 610 / 工作单位名称 685 / 部门 815 / 职务 925 / 手机号 1054 / 账号状态 1164 -->
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column prop="projectNo" label="支持意向项目编号" width="140" align="center" />
|
||||
<el-table-column prop="projectName" label="支持意向项目名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="name" label="姓名" width="80" align="center" />
|
||||
<el-table-column prop="workUnit" label="工作单位名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="department" label="部门" width="120" align="center" />
|
||||
<el-table-column prop="position" label="职务" width="120" align="center" />
|
||||
<el-table-column prop="phone" label="手机号" width="130" align="center" />
|
||||
<el-table-column label="账号状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.accountStatus==='存在' ? 'success' : 'warning'">{{ row.accountStatus || '不存在' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- ========== 筛选区 (与 People.vue 风格一致) ========== -->
|
||||
<el-form inline :model="q" class="filter-form">
|
||||
<el-form-item label="项目编号"><el-input v-model="q.projectNo" placeholder="如 ZH-2026-658" clearable /></el-form-item>
|
||||
<el-form-item label="意向项目名称"><el-input v-model="q.projectName" placeholder="输入意向项目名称" clearable /></el-form-item>
|
||||
<el-form-item label="姓名"><el-input v-model="q.name" placeholder="输入姓名" clearable /></el-form-item>
|
||||
<el-form-item label="工作单位"><el-input v-model="q.workUnit" placeholder="输入工作单位" clearable /></el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">查找</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- ========== 表格 (与 People.vue 风格一致, 无 page-card 包裹) ========== -->
|
||||
<el-table :data="rows" v-loading="loading" stripe border>
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column prop="projectNo" label="支持意向项目编号" width="140" align="center" />
|
||||
<el-table-column prop="projectName" label="支持意向项目名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="name" label="姓名" width="80" align="center" />
|
||||
<el-table-column prop="workUnit" label="工作单位名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="department" label="部门" width="120" align="center" />
|
||||
<el-table-column prop="position" label="职务" width="120" align="center" />
|
||||
<el-table-column prop="phone" label="手机号" width="130" align="center" />
|
||||
<el-table-column label="账号状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.accountStatus==='存在' ? 'success' : 'warning'">{{ row.accountStatus || '不存在' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pager">
|
||||
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,20 +66,23 @@ onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-support-intent { padding: 16px; }
|
||||
.page-card { background: #fff; border-radius: 6px; padding: 16px; border: 1px solid #ebeef5; margin-bottom: 12px; }
|
||||
.page-title { font-size: 20px; font-weight: 600; margin-bottom: 4px; padding-left: 10px; border-left: 3px solid var(--brand-primary); }
|
||||
.filter-tip { color: #909399; font-size: 12px; line-height: 1.8; }
|
||||
.page-toolbar { display: flex; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; align-items: center; }
|
||||
.page-toolbar :deep(.action-btn) {
|
||||
height: 36px; padding: 0 20px; font-size: 14px; border-radius: 4px;
|
||||
background: var(--brand-primary); color: #fff; border: 1px solid var(--brand-primary);
|
||||
display: inline-flex; align-items: center; justify-content: center; white-space: nowrap;
|
||||
transition: opacity .15s; margin-left: 0;
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
.filter-form { margin-bottom: 12px; }
|
||||
.pager { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
|
||||
/* 红字提示 (与 People.vue 一致) */
|
||||
.hint-list {
|
||||
background: #fff;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 8px;
|
||||
padding: 12px 20px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 12px;
|
||||
color: #ff4d4f;
|
||||
line-height: 1.8;
|
||||
}
|
||||
.page-toolbar :deep(.action-btn:hover) { opacity: .85; }
|
||||
.page-toolbar :deep(.action-btn.secondary) {
|
||||
background: #fff; color: var(--brand-primary); border: 1px solid var(--brand-primary);
|
||||
}
|
||||
.page-toolbar :deep(.action-btn.secondary:hover) { background: rgba(30,58,138,.06); }
|
||||
.hint-list p { margin-bottom: 4px; }
|
||||
.hint-list p:last-child { margin-bottom: 0; }
|
||||
</style>
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<template>
|
||||
<div class="manager-workbench">
|
||||
<div class="page-card manager-workbench">
|
||||
<div class="breadcrumb">首页 / 工作台</div>
|
||||
|
||||
<!-- 我的项目策划方案 标题 (原 top=142) -->
|
||||
<h2 class="page-title">我的项目策划方案</h2>
|
||||
|
||||
<!-- 5 个 KPI 卡 (原 top=165 已结算/已结题 + top=458 已执行/未执行) -->
|
||||
<!-- 5 个 KPI 卡 -->
|
||||
<div class="stats-grid">
|
||||
<router-link class="stat-card" to="/manager/projects">
|
||||
<div class="stat-label">项目总数量</div>
|
||||
@@ -30,7 +28,7 @@
|
||||
|
||||
<p class="hint-text">*点击数字,跳转到相应的列表页</p>
|
||||
|
||||
<!-- 消息通知 (新增) -->
|
||||
<!-- 消息通知 -->
|
||||
<section class="section">
|
||||
<h2 class="section-title">消息通知<a class="more" href="javascript:void(0)">更多 →</a></h2>
|
||||
<ul class="notice-list">
|
||||
@@ -100,23 +98,61 @@ onMounted(() => { loadStats(); loadNotices() })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整页面板 (与 People.vue 风格一致) */
|
||||
.manager-workbench { padding: 16px; }
|
||||
.page-title { font-size: 20px; font-weight: 600; color: #1a1a1a; margin-bottom: 16px; padding-left: 10px; border-left: 3px solid var(--brand-primary); }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 12px; }
|
||||
|
||||
/* 5 个 KPI 卡 (跟 executor/Overview 一致) */
|
||||
.stats-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; margin-bottom: 12px; }
|
||||
.stat-card {
|
||||
background: #fff; border-radius: 4px; padding: 24px;
|
||||
border: 1px solid #ebeef5; cursor: pointer; text-decoration: none; color: inherit;
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
background: #fff;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: opacity .15s, border-color .15s;
|
||||
min-height: 120px;
|
||||
}
|
||||
.stat-card:hover { border-color: var(--brand-primary); opacity: .9; }
|
||||
.stat-label { font-size: 14px; color: #606266; margin-bottom: 16px; }
|
||||
.stat-value { font-size: 32px; font-weight: 600; color: var(--brand-primary); line-height: 1.2; }
|
||||
.stat-label { font-size: 14px; color: #8c8c8c; margin-bottom: 16px; }
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
background: linear-gradient(135deg, var(--brand-primary) 0%, var(--brand-primary-deep) 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.hint-text { font-size: 12px; color: #ff4d4f; margin: 12px 0 20px; text-align: center; }
|
||||
.section { background: #fff; border-radius: 4px; padding: 20px 24px; border: 1px solid #ebeef5; }
|
||||
.section-title { font-size: 15px; font-weight: 600; color: #1a1a1a; margin-bottom: 16px; padding-left: 10px; border-left: 3px solid var(--brand-primary); display: flex; justify-content: space-between; }
|
||||
|
||||
/* 消息通知 */
|
||||
.section {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px 24px;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16px;
|
||||
padding-left: 10px;
|
||||
border-left: 3px solid var(--brand-primary);
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.more { font-size: 12px; color: var(--brand-primary); text-decoration: none; }
|
||||
.more:hover { text-decoration: underline; }
|
||||
.notice-list { list-style: none; border-top: 1px solid #f0f0f0; }
|
||||
.notice-item { padding: 12px 0; border-bottom: 1px solid #f0f0f0; display: flex; align-items: center; gap: 12px; }
|
||||
.notice-item:last-child { border-bottom: none; }
|
||||
|
||||
Reference in New Issue
Block a user