Merge branch 'master' of http://10.31.100.4:8418/yunzerwebsite/yunzerwebsiteallinone
This commit is contained in:
@@ -23,22 +23,22 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="stats-row">
|
||||
<div class="stat-card blue">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">核算员工</div>
|
||||
<div class="stat-value">{{ dashboard.employee_count || 0 }}</div>
|
||||
<div class="stat-sub">{{ dashboard.payroll_month || dashboardMonth }} 薪资单</div>
|
||||
</div>
|
||||
<div class="stat-card purple">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">应发工资</div>
|
||||
<div class="stat-value">¥{{ money(dashboard.total_gross_salary) }}</div>
|
||||
<div class="stat-sub">税前及各类补贴合计</div>
|
||||
</div>
|
||||
<div class="stat-card green">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">实发工资</div>
|
||||
<div class="stat-value">¥{{ money(dashboard.total_net_salary) }}</div>
|
||||
<div class="stat-sub">扣除五险一金及个税后</div>
|
||||
</div>
|
||||
<div class="stat-card orange">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">待处理</div>
|
||||
<div class="stat-value">{{ (dashboard.draft_count || 0) + (dashboard.confirmed_count || 0) }}</div>
|
||||
<div class="stat-sub">草稿 {{ dashboard.draft_count || 0 }} / 待发放 {{ dashboard.confirmed_count || 0 }}</div>
|
||||
@@ -248,7 +248,7 @@
|
||||
</el-table>
|
||||
<div class="scheme-form" v-if="schemeFormVisible">
|
||||
<div class="section-title">{{ schemeEditingID ? "编辑薪酬方案" : "新增薪酬方案" }}</div>
|
||||
<el-form ref="schemeFormRef" :model="schemeForm" :rules="schemeRules" label-width="100px">
|
||||
<el-form ref="schemeFormRef" :model="schemeForm" :rules="schemeRules" label-width="120px">
|
||||
<div class="form-grid">
|
||||
<el-form-item label="方案名称" prop="scheme_name"><el-input v-model="schemeForm.scheme_name" /></el-form-item>
|
||||
<el-form-item label="适用员工" prop="employee_id"><el-select v-model="schemeForm.employee_id" filterable style="width: 100%"><el-option v-for="employee in employees" :key="employee.id" :label="employeeLabel(employee)" :value="employee.id" /></el-select></el-form-item>
|
||||
@@ -340,7 +340,7 @@ function money(value) { return Number(value || 0).toLocaleString("zh-CN", { mini
|
||||
function dateTime(value) { return value ? String(value).replace("T", " ").slice(0, 19) : "-" }
|
||||
function statusText(status) { return ["草稿", "已确认", "已发放", "已作废"][status] || "未知" }
|
||||
function statusType(status) { return ["info", "warning", "success", "danger"][status] || "info" }
|
||||
function employeeLabel(employee) { return `${employee.name}${employee.department ? `(${employee.department})` : ""}` }
|
||||
function employeeLabel(employee) { return `${employee.name}${employee.department_name ? `(${employee.department_name})` : (employee.department ? `(${employee.department})` : "")}` }
|
||||
function employeeName(id) { return employees.value.find(item => item.id === id)?.name || "-" }
|
||||
function fixedSchemeAmount(item) { return sum(item, ["base_salary", "post_allowance", "performance_salary", "transport_allowance", "meal_allowance", "communication_allowance"]) }
|
||||
|
||||
@@ -443,7 +443,7 @@ onMounted(async () => { await Promise.all([loadEmployees(), loadSchemes(), loadD
|
||||
.header-actions, .filter-bar { gap: 12px; }
|
||||
.dashboard-toolbar { justify-content: flex-end; gap: 10px; margin: -2px 0 10px; color: #606266; font-size: 13px; }
|
||||
.stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px; }
|
||||
.stat-card { padding: 15px 18px; background: #fff; border: 1px solid #ebeef5; border-radius: 8px; border-top: 3px solid #409eff; }
|
||||
.stat-card { padding: 15px 18px; background: #fff; border: 1px solid #ebeef5; border-radius: 8px; }
|
||||
.stat-card.purple { border-top-color: #8b5cf6; }.stat-card.green { border-top-color: #67c23a; }.stat-card.orange { border-top-color: #e6a23c; }
|
||||
.stat-label, .stat-sub { color: #909399; font-size: 13px; }.stat-value { margin: 7px 0 4px; font-size: 25px; font-weight: 600; color: #303133; }.stat-sub { font-size: 12px; }
|
||||
.table-card { padding: 16px; background: #fff; border: 1px solid #ebeef5; border-radius: 8px; }.filter-bar { flex-wrap: wrap; margin-bottom: 14px; }.pagination { display: flex; justify-content: flex-end; margin-top: 16px; }
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
<el-descriptions-item label="微信号">
|
||||
<span>{{ contact.wechat || '-' }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="QQ">
|
||||
<span>{{ contact.qq || '-' }}</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="title"
|
||||
width="620px"
|
||||
width="720px"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
>
|
||||
@@ -13,150 +13,200 @@
|
||||
label-width="100px"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item label="联系人类型" prop="contact_type">
|
||||
<el-radio-group v-model="form.contact_type">
|
||||
<el-radio :value="1">内部员工</el-radio>
|
||||
<el-radio :value="2">外部联系人</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="联系人类型" prop="contact_type">
|
||||
<el-radio-group v-model="form.contact_type">
|
||||
<el-radio :value="1">内部员工</el-radio>
|
||||
<el-radio :value="2">外部联系人</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="姓名" prop="contact_name">
|
||||
<el-input
|
||||
v-model="form.contact_name"
|
||||
placeholder="请输入联系人姓名"
|
||||
maxlength="64"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="contact_name">
|
||||
<el-input
|
||||
v-model="form.contact_name"
|
||||
placeholder="请输入联系人姓名"
|
||||
maxlength="64"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-radio-group v-model="form.gender">
|
||||
<el-radio :value="1">男</el-radio>
|
||||
<el-radio :value="2">女</el-radio>
|
||||
<el-radio :value="0">未知</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-radio-group v-model="form.gender">
|
||||
<el-radio :value="1">男</el-radio>
|
||||
<el-radio :value="2">女</el-radio>
|
||||
<el-radio :value="0">未知</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20" v-if="form.contact_type === 1">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属部门" prop="org_id">
|
||||
<el-tree-select
|
||||
v-model="form.org_id"
|
||||
:data="orgOptions"
|
||||
:props="orgTreeProps"
|
||||
placeholder="请选择组织架构/部门"
|
||||
clearable
|
||||
check-strictly
|
||||
style="width: 100%"
|
||||
@change="handleOrgChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职位" prop="position_id">
|
||||
<el-select
|
||||
v-model="form.position_id"
|
||||
placeholder="请选择职位"
|
||||
clearable
|
||||
filterable
|
||||
:loading="positionLoading"
|
||||
style="width: 100%"
|
||||
@change="handlePositionChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in positionOptions"
|
||||
:key="item.id"
|
||||
:label="item.position_name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item v-if="form.contact_type === 1" label="所属部门" prop="org_id">
|
||||
<el-tree-select
|
||||
v-model="form.org_id"
|
||||
:data="orgOptions"
|
||||
:props="orgTreeProps"
|
||||
placeholder="请选择组织架构/部门"
|
||||
clearable
|
||||
check-strictly
|
||||
style="width: 100%"
|
||||
@change="handleOrgChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机号" prop="phone">
|
||||
<el-input
|
||||
v-model="form.phone"
|
||||
placeholder="请输入手机号"
|
||||
maxlength="20"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="办公电话" prop="work_phone">
|
||||
<el-input
|
||||
v-model="form.work_phone"
|
||||
placeholder="请输入办公电话"
|
||||
maxlength="20"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item v-if="form.contact_type === 1" label="职位" prop="position_id">
|
||||
<el-select
|
||||
v-model="form.position_id"
|
||||
placeholder="请选择职位"
|
||||
clearable
|
||||
filterable
|
||||
:loading="positionLoading"
|
||||
style="width: 100%"
|
||||
@change="handlePositionChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in positionOptions"
|
||||
:key="item.id"
|
||||
:label="item.position_name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input
|
||||
v-model="form.email"
|
||||
placeholder="请输入邮箱"
|
||||
maxlength="128"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="微信号" prop="wechat">
|
||||
<el-input
|
||||
v-model="form.wechat"
|
||||
placeholder="请输入微信号"
|
||||
maxlength="64"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="手机号" prop="phone">
|
||||
<el-input
|
||||
v-model="form.phone"
|
||||
placeholder="请输入手机号"
|
||||
maxlength="20"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="QQ" prop="qq">
|
||||
<el-input
|
||||
v-model="form.qq"
|
||||
placeholder="请输入QQ号"
|
||||
maxlength="20"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :value="1">正常</el-radio>
|
||||
<el-radio :value="0">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="办公电话" prop="work_phone">
|
||||
<el-input
|
||||
v-model="form.work_phone"
|
||||
placeholder="请输入办公电话"
|
||||
maxlength="20"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20" v-if="form.contact_type === 2">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公司名称" prop="company_name">
|
||||
<el-input
|
||||
v-model="form.company_name"
|
||||
placeholder="请输入公司名称"
|
||||
maxlength="128"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="部门" prop="dept_name">
|
||||
<el-input
|
||||
v-model="form.dept_name"
|
||||
placeholder="请输入部门名称"
|
||||
maxlength="128"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input
|
||||
v-model="form.email"
|
||||
placeholder="请输入邮箱"
|
||||
maxlength="128"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20" v-if="form.contact_type === 2">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="职位" prop="position_title">
|
||||
<el-input
|
||||
v-model="form.position_title"
|
||||
placeholder="请输入职位"
|
||||
maxlength="100"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="微信号" prop="wechat">
|
||||
<el-input
|
||||
v-model="form.wechat"
|
||||
placeholder="请输入微信号"
|
||||
maxlength="64"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="地址" prop="address">
|
||||
<el-input
|
||||
v-model="form.address"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入地址"
|
||||
maxlength="512"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item v-if="form.contact_type === 2" label="公司名称" prop="company_name">
|
||||
<el-input
|
||||
v-model="form.company_name"
|
||||
placeholder="请输入公司名称"
|
||||
maxlength="128"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.contact_type === 2" label="部门" prop="dept_name">
|
||||
<el-input
|
||||
v-model="form.dept_name"
|
||||
placeholder="请输入部门名称"
|
||||
maxlength="128"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.contact_type === 2" label="职位" prop="position_title">
|
||||
<el-input
|
||||
v-model="form.position_title"
|
||||
placeholder="请输入职位"
|
||||
maxlength="100"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="地址" prop="address">
|
||||
<el-input
|
||||
v-model="form.address"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入地址"
|
||||
maxlength="512"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入备注"
|
||||
maxlength="512"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" :max="99999" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :value="1">正常</el-radio>
|
||||
<el-radio :value="0">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入备注"
|
||||
maxlength="512"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
@@ -173,7 +223,7 @@
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getOrganizationList, getPositionList } from '@/api/contactOA'
|
||||
import { getOrganizationList, getPositionList, getPositionDetail } from '@/api/contactOA'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: { type: Boolean, default: false },
|
||||
@@ -201,6 +251,7 @@ const emptyForm = () => ({
|
||||
work_phone: '',
|
||||
email: '',
|
||||
wechat: '',
|
||||
qq: '',
|
||||
avatar: '',
|
||||
org_id: null,
|
||||
company_name: '',
|
||||
@@ -209,7 +260,6 @@ const emptyForm = () => ({
|
||||
position_title: '',
|
||||
address: '',
|
||||
remark: '',
|
||||
sort: 0,
|
||||
status: 1
|
||||
})
|
||||
|
||||
@@ -270,45 +320,39 @@ const loadOrgOptions = async () => {
|
||||
const positionOptions = ref([])
|
||||
const positionLoading = ref(false)
|
||||
|
||||
// 收集部门自身及其所有上级组织ID(职位可挂在任意层级组织上,如集团级“总经理”)
|
||||
const collectOrgSelfAndAncestors = (deptId) => {
|
||||
const ids = new Set()
|
||||
if (!deptId) return ids
|
||||
const parentMap = {}
|
||||
const walk = (nodes) => {
|
||||
nodes.forEach((n) => {
|
||||
parentMap[n.id] = n.parent_id
|
||||
if (n.children?.length) walk(n.children)
|
||||
})
|
||||
}
|
||||
walk(orgOptions.value)
|
||||
let cur = Number(deptId)
|
||||
while (cur && !ids.has(cur)) {
|
||||
ids.add(cur)
|
||||
cur = parentMap[cur]
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// 职位归属由 department_id 决定:只取挂在所选部门下的职位,
|
||||
// 不再向上追溯到上级组织(否则选了"运维部"会把"总经办"的职位也带出来)。
|
||||
const loadPositionOptions = async (deptId) => {
|
||||
positionLoading.value = true
|
||||
try {
|
||||
const res = await getPositionList()
|
||||
const params = deptId ? { department_id: deptId } : {}
|
||||
const res = await getPositionList(params)
|
||||
const data = res?.data || res || []
|
||||
const list = Array.isArray(data) ? data : []
|
||||
const enabled = list.filter((p) => p.status === 1)
|
||||
if (!deptId) {
|
||||
positionOptions.value = enabled
|
||||
} else {
|
||||
// 允许选择本部门及其上级组织的职位
|
||||
const allowed = collectOrgSelfAndAncestors(deptId)
|
||||
positionOptions.value = enabled.filter((p) => allowed.has(Number(p.department_id)))
|
||||
}
|
||||
positionOptions.value = list.filter((p) => p.status === 1)
|
||||
} catch (error) {
|
||||
positionOptions.value = []
|
||||
} finally {
|
||||
positionLoading.value = false
|
||||
}
|
||||
await ensureCurrentPosition()
|
||||
}
|
||||
|
||||
// 编辑历史数据时,已选职位可能挂在其它组织上(如集团级的“总经理”),
|
||||
// 这时把它补进选项,保证回显出职位名称而不是一个裸 ID。
|
||||
const ensureCurrentPosition = async () => {
|
||||
const positionId = form.value?.position_id
|
||||
if (!positionId) return
|
||||
if (positionOptions.value.some((p) => Number(p.id) === Number(positionId))) return
|
||||
try {
|
||||
const res = await getPositionDetail(positionId)
|
||||
const detail = res?.data || res
|
||||
if (detail?.id) {
|
||||
positionOptions.value = [detail, ...positionOptions.value]
|
||||
}
|
||||
} catch (error) {
|
||||
// silent
|
||||
}
|
||||
}
|
||||
|
||||
const handleOrgChange = (val) => {
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
{{ row.contact_name?.charAt(0) }}
|
||||
</el-avatar>
|
||||
<div class="contact-name-info">
|
||||
<span class="contact-name">{{ row.contact_name }}</span>
|
||||
<span class="contact-name" @click.stop="openDetail(row)">{{ row.contact_name }}</span>
|
||||
<el-tag
|
||||
:type="row.contact_type === 1 ? 'primary' : 'info'"
|
||||
size="small"
|
||||
@@ -106,38 +106,37 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="phone" label="手机号" width="140" />
|
||||
<el-table-column prop="org_name" label="部门" min-width="140">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.org_name || row.dept_name || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="position_title" label="职位" min-width="120">
|
||||
<el-table-column prop="position_title" label="职位" width="140">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.position_title || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="org_name" label="部门" width="140">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.org_name || row.dept_name || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="phone" label="手机号" width="140" />
|
||||
<!-- <el-table-column prop="wechat" label="微信" width="180">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.wechat || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="qq" label="QQ" width="140">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.qq || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>-->
|
||||
<el-table-column prop="email" label="邮箱" min-width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.email || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="wechat" label="微信" width="120">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.wechat || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="120">
|
||||
<el-table-column label="操作" fixed="right" width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" size="small" title="编辑" @click.stop="openEditContact(row)">
|
||||
<el-icon><Edit /></el-icon>
|
||||
</el-button>
|
||||
<el-button link type="primary" size="small" title="详情" @click.stop="openDetail(row)">
|
||||
<el-icon><View /></el-icon>
|
||||
</el-button>
|
||||
<el-button link type="danger" size="small" title="删除" @click.stop="handleDelete(row)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -323,6 +322,7 @@ const editFormData = reactive({
|
||||
work_phone: '',
|
||||
email: '',
|
||||
wechat: '',
|
||||
qq: '',
|
||||
avatar: '',
|
||||
org_id: null,
|
||||
company_name: '',
|
||||
@@ -331,7 +331,6 @@ const editFormData = reactive({
|
||||
position_title: '',
|
||||
address: '',
|
||||
remark: '',
|
||||
sort: 0,
|
||||
status: 1
|
||||
})
|
||||
|
||||
@@ -354,7 +353,6 @@ const openCreateContact = () => {
|
||||
position_title: '',
|
||||
address: '',
|
||||
remark: '',
|
||||
sort: 0,
|
||||
status: 1
|
||||
})
|
||||
editDialogVisible.value = true
|
||||
@@ -371,6 +369,7 @@ const openEditContact = (row) => {
|
||||
work_phone: row.work_phone,
|
||||
email: row.email,
|
||||
wechat: row.wechat,
|
||||
qq: row.qq,
|
||||
avatar: row.avatar,
|
||||
org_id: row.org_id,
|
||||
company_name: row.company_name,
|
||||
@@ -379,7 +378,6 @@ const openEditContact = (row) => {
|
||||
position_title: row.position_title,
|
||||
address: row.address,
|
||||
remark: row.remark,
|
||||
sort: row.sort,
|
||||
status: row.status
|
||||
})
|
||||
editDialogVisible.value = true
|
||||
@@ -415,20 +413,6 @@ const handleDetailEdit = (row) => {
|
||||
openEditContact(row)
|
||||
}
|
||||
|
||||
// ---- 删除 ----
|
||||
const handleDelete = async (row) => {
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认删除联系人「${row.contact_name}」吗?`, '删除确认', { type: 'warning' })
|
||||
await deleteContact(row.id)
|
||||
ElMessage.success('删除成功')
|
||||
await loadContactList()
|
||||
} catch (error) {
|
||||
if (error !== 'cancel' && error !== 'close') {
|
||||
ElMessage.error(error?.message || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadOrgTree()
|
||||
loadContactList()
|
||||
@@ -585,7 +569,12 @@ onMounted(() => {
|
||||
|
||||
.contact-name {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.contact-name:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.contact-type-tag {
|
||||
|
||||
@@ -451,6 +451,14 @@ const handleSchedulePostpone = (item) => {
|
||||
|
||||
const goSchedule = () => router.push("/apps/oa/schedule");
|
||||
|
||||
// 跳转到日程管理页并打开该日程的编辑抽屉
|
||||
const editSchedule = (item) => {
|
||||
// 通过 sessionStorage 把待编辑日程传递给日程管理页,由其打开编辑抽屉
|
||||
sessionStorage.setItem("schedule_edit_item", JSON.stringify(item));
|
||||
scheduleActionVisible.value = false;
|
||||
router.push("/apps/oa/schedule");
|
||||
};
|
||||
|
||||
const loadDashboard = async () => {
|
||||
try {
|
||||
const data = responseData(await getReimbursementDashboard());
|
||||
@@ -605,6 +613,18 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.trend-card {
|
||||
height: 398px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.chart-container {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.type-card {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@@ -621,6 +641,23 @@ onBeforeUnmount(() => {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.schedule-tabs {
|
||||
margin-bottom: 20px;
|
||||
|
||||
:deep(.el-tabs__header) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav-wrap::after) {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.schedule-list {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -742,6 +779,42 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.schedule-action-content {
|
||||
.schedule-action-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.schedule-action-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.overdue {
|
||||
color: #f56c6c;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.schedule-action-tip {
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.schedule-action-btns {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-dist,
|
||||
.type-dist {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user