This commit is contained in:
wk committed 2026-10-07 08:59:03 +08:00
commit 737244fa9e
36 files changed
+3309 -246

No files matched your search

+13 -13
View File
@@ -5,23 +5,23 @@
<div class="breadcrumb">
<span>运营管控体系</span>
<span class="sep">/</span>
<span>运营派单</span>
<span>项目管理</span>
<span class="sep">/</span>
<span class="cur">电工派单成本价</span>
<span class="cur">勘察费用</span>
</div>
<div class="header-main">
<div class="header-left">
<div class="header-row">
<span class="title-bar"></span>
<span class="main-title">电工派单成本价</span>
<span class="sub-title">DISPATCH COST PRICE</span>
<span class="main-title">勘察费用</span>
<span class="sub-title">SURVEY FEE</span>
</div>
<p class="desc">维护共享电工派单的成本价目,按派单类型区分单价或总价提成,支持按次、按工时两种计价方式。</p>
<p class="desc">维护勘察派单相关费用标准(基础出场费、回路测点补贴等),支持按次、按工时两种计价方式。</p>
</div>
<div class="header-actions">
<a-button v-if="canCreate" type="primary" @click="handleAdd">
<template #icon><PlusOutlined /></template>
新增成本价
新增勘察费用
</a-button>
</div>
</div>
@@ -88,7 +88,7 @@
<div class="list-header">
<div class="list-title">
<span class="dot"></span>
<span class="t">电工派单成本价清单</span>
<span class="t">勘察费用清单</span>
<span class="count">{{ total }}</span>
</div>
<a-button type="text" size="small" title="刷新列表" @click="fetchList">
@@ -152,7 +152,7 @@
</a-button>
<a-popconfirm
v-if="canDelete"
title="确定要删除该成本价吗?"
title="确定要删除该勘察费用吗?"
ok-text="确定"
cancel-text="取消"
ok-button-props="{ danger: true }"
@@ -168,7 +168,7 @@
</template>
<template #emptyText>
<a-empty description="暂无成本价数据" />
<a-empty description="暂无勘察费用数据" />
</template>
</a-table>
</div>
@@ -203,7 +203,7 @@
<div class="section-head">
<span class="section-no">01</span>
<div class="section-text">
<span class="section-name">成本价信息</span>
<span class="section-name">勘察费用信息</span>
<span class="section-sub">Cost Price Information</span>
</div>
</div>
@@ -367,7 +367,7 @@ async function fetchList() {
total.value = res.data.total;
}
} catch (error) {
message.error('获取电工派单成本价列表失败');
message.error('获取勘察费用列表失败');
} finally {
loading.value = false;
}
@@ -399,7 +399,7 @@ function handleAdd() {
isEdit.value = false;
editId.value = null;
editCode.value = '';
modalTitle.value = '新增成本价';
modalTitle.value = '新增勘察费用';
resetForm();
modalVisible.value = true;
}
@@ -408,7 +408,7 @@ function handleEdit(record: DispatchPriceInfo) {
isEdit.value = true;
editId.value = record.id;
editCode.value = record.priceCode;
modalTitle.value = '编辑成本价';
modalTitle.value = '编辑勘察费用';
resetForm();
formData.dispatchType = record.dispatchType || undefined;
@@ -0,0 +1,227 @@
<template>
<div class="receiver-editor">
<div class="re-section">
<div class="re-section-title">管理端用户</div>
<div class="re-field">
<label class="re-label">按角色</label>
<a-select
v-model:value="config.users.roles"
mode="multiple"
placeholder="选择角色编码(可多选)"
allow-clear
:options="roleOptions"
:loading="roleLoading"
style="width: 100%"
/>
</div>
<div class="re-field">
<label class="re-label">按用户</label>
<a-select
v-model:value="config.users.ids"
mode="multiple"
placeholder="选择具体用户(可多选)"
allow-clear
show-search
option-filter-prop="label"
:options="userOptions"
:loading="userLoading"
style="width: 100%"
/>
</div>
</div>
<div class="re-section">
<div class="re-section-title">电工</div>
<div class="re-field re-field-block">
<label class="re-label">接收方式</label>
<a-radio-group v-model:value="config.workers.mode" class="re-radio">
<a-radio value="none">不发送</a-radio>
<a-radio v-if="allowEventMode" value="event">事件关联电工</a-radio>
<a-radio value="all">全部在岗电工</a-radio>
<a-radio value="ids">指定电工</a-radio>
<a-radio value="status">按状态筛选</a-radio>
</a-radio-group>
</div>
<div v-if="config.workers.mode === 'ids'" class="re-field">
<label class="re-label">指定电工</label>
<a-select
v-model:value="config.workers.ids"
mode="multiple"
placeholder="选择电工(可多选)"
allow-clear
show-search
option-filter-prop="label"
:options="workerOptions"
:loading="workerLoading"
style="width: 100%"
/>
</div>
<div v-if="config.workers.mode === 'status'" class="re-field">
<label class="re-label">审核状态</label>
<a-select
v-model:value="config.workers.auditStatus"
placeholder="全部审核状态"
allow-clear
:options="auditOptions"
style="width: 100%"
/>
</div>
<div v-if="config.workers.mode === 'status'" class="re-field">
<label class="re-label">在岗状态</label>
<a-select
v-model:value="config.workers.status"
placeholder="全部在岗状态"
allow-clear
:options="statusOptions"
style="width: 100%"
/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { roleApi } from '@/api/role';
import { userApi } from '@/api/user';
import { workerApi } from '@/api/worker';
import type { ReceiverConfig } from '@/api/noticeRule';
withDefaults(
defineProps<{
// 直接持有的响应式接收对象配置(嵌套字段就地修改,父级实时感知)
config: ReceiverConfig;
// 手动群发无「事件关联」上下文,可关闭该选项
allowEventMode?: boolean;
}>(),
{ allowEventMode: true }
);
const roleOptions = ref<{ value: string; label: string }[]>([]);
const userOptions = ref<{ value: number; label: string }[]>([]);
const workerOptions = ref<{ value: number; label: string }[]>([]);
const roleLoading = ref(false);
const userLoading = ref(false);
const workerLoading = ref(false);
const auditOptions = [
{ value: 0, label: '待审核' },
{ value: 1, label: '已通过' },
{ value: 2, label: '已驳回' },
];
const statusOptions = [
{ value: 1, label: '在岗' },
{ value: 0, label: '离职' },
];
// 角色/用户/电工下拉为可选增强项,拉取失败(如无对应菜单权限)不阻断配置
async function loadRoles() {
roleLoading.value = true;
try {
const res = await roleApi.getAllRoles();
if (res.code === 200) {
roleOptions.value = (res.data || []).map((r) => ({
value: r.roleCode,
label: `${r.roleName}(${r.roleCode})`,
}));
}
} catch {
// 忽略:无权限时由用户手动维护角色编码
} finally {
roleLoading.value = false;
}
}
async function loadUsers() {
userLoading.value = true;
try {
const res = await userApi.getUserList({ page: 1, pageSize: 200 });
if (res.code === 200) {
userOptions.value = (res.data?.list || []).map((u) => ({
value: u.id,
label: `${u.realName || u.username}(${u.username})`,
}));
}
} catch {
// 忽略
} finally {
userLoading.value = false;
}
}
async function loadWorkers() {
workerLoading.value = true;
try {
const res = await workerApi.getOptions();
if (res.code === 200) {
workerOptions.value = (res.data || []).map((w) => ({
value: w.id,
label: w.workerTitle ? `${w.workerName}(${w.workerTitle})` : w.workerName,
}));
}
} catch {
// 忽略
} finally {
workerLoading.value = false;
}
}
onMounted(() => {
loadRoles();
loadUsers();
loadWorkers();
});
</script>
<style scoped>
.receiver-editor {
display: flex;
flex-direction: column;
gap: 14px;
}
.re-section {
border: 1px solid #eef1f6;
border-radius: 8px;
padding: 12px 14px;
background: #f8faff;
}
.re-section-title {
font-size: 13px;
font-weight: 700;
color: #0d1c2c;
margin-bottom: 10px;
}
.re-field {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
.re-field:last-child {
margin-bottom: 0;
}
.re-field-block {
align-items: flex-start;
}
.re-label {
flex-shrink: 0;
width: 72px;
font-size: 12px;
color: #5b6b7e;
}
.re-radio {
line-height: 2;
}
</style>
File diff suppressed because it is too large. Load diff