mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-09 10:00:30 +08:00
feat(m1): add project stakeholder CRUD
This commit is contained in:
@@ -437,3 +437,16 @@ export function updateJsonTemplate(id, body) {
|
||||
export function deleteJsonTemplate(id) {
|
||||
return axios.delete(`/api/v1/integration/json-templates/${id}`);
|
||||
}
|
||||
|
||||
export function listStakeholders(projectId) {
|
||||
return axios.get(`/api/v1/projects/${projectId}/stakeholders`);
|
||||
}
|
||||
export function addStakeholder(projectId, body) {
|
||||
return axios.post(`/api/v1/projects/${projectId}/stakeholders`, body);
|
||||
}
|
||||
export function updateStakeholder(projectId, id, body) {
|
||||
return axios.put(`/api/v1/projects/${projectId}/stakeholders/${id}`, body);
|
||||
}
|
||||
export function deleteStakeholder(projectId, id) {
|
||||
return axios.delete(`/api/v1/projects/${projectId}/stakeholders/${id}`);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/>
|
||||
</el-select>
|
||||
<el-button type="primary" :loading="loading" @click="load">查询</el-button>
|
||||
<el-button type="success" @click="openCreate">新建项目</el-button>
|
||||
<el-button v-permission="'project:rw'" type="success" @click="openCreate">新建项目</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -38,10 +38,11 @@
|
||||
{{ phaseLabel(row.phase) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="160" fixed="right">
|
||||
<el-table-column label="操作" width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="openEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" link @click="onDelete(row)">删除</el-button>
|
||||
<el-button type="primary" link @click="openStakeholderDialog(row)">干系人</el-button>
|
||||
<el-button v-permission="'project:rw'" type="primary" link @click="openEdit(row)">编辑</el-button>
|
||||
<el-button v-permission="'project:delete'" type="danger" link @click="onDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -100,6 +101,50 @@
|
||||
<el-button type="primary" :loading="saving" @click="submit">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="stakeholderVisible" :title="stakeholderTitle" width="700px" destroy-on-close>
|
||||
<el-button type="primary" size="small" style="margin-bottom: 12px" @click="openStakeholderAdd">添加干系人</el-button>
|
||||
<el-table :data="stakeholderRows" stripe style="width: 100%">
|
||||
<el-table-column prop="contactName" label="姓名" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="contactRole" label="角色" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="phone" label="电话" min-width="130" />
|
||||
<el-table-column prop="email" label="邮箱" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column label="内部人员" width="90">
|
||||
<template #default="{ row }">
|
||||
{{ row.isInternal ? '是' : '否' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="openStakeholderEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" link @click="onStakeholderDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="stakeholderFormVisible" :title="stakeholderFormTitle" width="500px" destroy-on-close @closed="resetStakeholderForm">
|
||||
<el-form ref="stakeholderFormRef" :model="stakeholderForm" :rules="stakeholderRules" label-width="100px">
|
||||
<el-form-item label="姓名" prop="contactName">
|
||||
<el-input v-model="stakeholderForm.contactName" maxlength="128" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="角色" prop="contactRole">
|
||||
<el-input v-model="stakeholderForm.contactRole" maxlength="64" placeholder="请输入角色" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="stakeholderForm.phone" maxlength="32" placeholder="请输入电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="stakeholderForm.email" maxlength="128" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
<el-form-item label="内部人员">
|
||||
<el-switch v-model="stakeholderForm.isInternal" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="stakeholderFormVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="stakeholderSaving" @click="submitStakeholder">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
@@ -114,6 +159,10 @@ import {
|
||||
updateProject,
|
||||
deleteProject,
|
||||
getProjectPhaseDictionary,
|
||||
listStakeholders,
|
||||
addStakeholder,
|
||||
updateStakeholder,
|
||||
deleteStakeholder,
|
||||
} from "../api/platform";
|
||||
import { apiErrorMessage } from "../utils/apiErrorMessage";
|
||||
|
||||
@@ -151,6 +200,128 @@ const rules = {
|
||||
|
||||
const dialogTitle = computed(() => (editingId.value ? "编辑项目" : "新建项目"));
|
||||
|
||||
// —— 干系人 ——————————————————————————————————————————
|
||||
const stakeholderVisible = ref(false);
|
||||
const stakeholderFormVisible = ref(false);
|
||||
const stakeholderSaving = ref(false);
|
||||
const stakeholderRows = ref([]);
|
||||
const stakeholderProjectId = ref(null);
|
||||
const stakeholderEditingId = ref(null);
|
||||
const stakeholderFormRef = ref(null);
|
||||
const stakeholderForm = reactive({
|
||||
contactName: "",
|
||||
contactRole: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
isInternal: false,
|
||||
});
|
||||
|
||||
const stakeholderRules = {
|
||||
contactName: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
||||
};
|
||||
|
||||
const stakeholderTitle = computed(() => {
|
||||
const p = rows.value.find((r) => r.id === stakeholderProjectId.value);
|
||||
return `干系人 - ${p?.name ?? stakeholderProjectId.value}`;
|
||||
});
|
||||
|
||||
const stakeholderFormTitle = computed(() =>
|
||||
stakeholderEditingId.value ? "编辑干系人" : "添加干系人"
|
||||
);
|
||||
|
||||
function openStakeholderDialog(row) {
|
||||
stakeholderProjectId.value = row.id;
|
||||
stakeholderVisible.value = true;
|
||||
loadStakeholders();
|
||||
}
|
||||
|
||||
async function loadStakeholders() {
|
||||
try {
|
||||
const { data } = await listStakeholders(stakeholderProjectId.value);
|
||||
stakeholderRows.value = Array.isArray(data) ? data : [];
|
||||
} catch (e) {
|
||||
ElMessage.error(apiErrorMessage(e, "加载干系人列表失败"));
|
||||
stakeholderRows.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
function openStakeholderAdd() {
|
||||
stakeholderEditingId.value = null;
|
||||
resetStakeholderForm();
|
||||
stakeholderFormVisible.value = true;
|
||||
}
|
||||
|
||||
function openStakeholderEdit(row) {
|
||||
stakeholderEditingId.value = row.id;
|
||||
stakeholderForm.contactName = row.contactName ?? "";
|
||||
stakeholderForm.contactRole = row.contactRole ?? "";
|
||||
stakeholderForm.phone = row.phone ?? "";
|
||||
stakeholderForm.email = row.email ?? "";
|
||||
stakeholderForm.isInternal = row.isInternal ?? false;
|
||||
stakeholderFormVisible.value = true;
|
||||
}
|
||||
|
||||
function resetStakeholderForm() {
|
||||
stakeholderForm.contactName = "";
|
||||
stakeholderForm.contactRole = "";
|
||||
stakeholderForm.phone = "";
|
||||
stakeholderForm.email = "";
|
||||
stakeholderForm.isInternal = false;
|
||||
stakeholderFormRef.value?.resetFields?.();
|
||||
}
|
||||
|
||||
async function submitStakeholder() {
|
||||
const f = stakeholderFormRef.value;
|
||||
if (!f) return;
|
||||
try {
|
||||
await f.validate();
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
stakeholderSaving.value = true;
|
||||
const payload = {
|
||||
contactName: stakeholderForm.contactName.trim(),
|
||||
contactRole: stakeholderForm.contactRole || null,
|
||||
phone: stakeholderForm.phone || null,
|
||||
email: stakeholderForm.email || null,
|
||||
isInternal: stakeholderForm.isInternal,
|
||||
};
|
||||
try {
|
||||
const pid = stakeholderProjectId.value;
|
||||
if (stakeholderEditingId.value != null) {
|
||||
await updateStakeholder(pid, stakeholderEditingId.value, payload);
|
||||
ElMessage.success("已保存");
|
||||
} else {
|
||||
await addStakeholder(pid, payload);
|
||||
ElMessage.success("已添加");
|
||||
}
|
||||
stakeholderFormVisible.value = false;
|
||||
await loadStakeholders();
|
||||
} catch (e) {
|
||||
ElMessage.error(apiErrorMessage(e, "保存失败"));
|
||||
} finally {
|
||||
stakeholderSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onStakeholderDelete(row) {
|
||||
ElMessageBox.confirm(`确定删除干系人「${row.contactName || row.id}」吗?`, "提示", {
|
||||
type: "warning",
|
||||
confirmButtonText: "删除",
|
||||
cancelButtonText: "取消",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
await deleteStakeholder(stakeholderProjectId.value, row.id);
|
||||
ElMessage.success("已删除");
|
||||
await loadStakeholders();
|
||||
} catch (e) {
|
||||
ElMessage.error(apiErrorMessage(e, "删除失败"));
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
const customerMap = computed(() => {
|
||||
const m = new Map();
|
||||
for (const c of customerOptions.value) {
|
||||
|
||||
Reference in New Issue
Block a user