From 5952d34811ee82e797ef0070f84ff041381072a5 Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期二, 10 三月 2026 17:52:40 +0800
Subject: [PATCH] 新增采购退货单增加费用等数据

---
 src/views/projectManagement/Management/index.vue |  333 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 333 insertions(+), 0 deletions(-)

diff --git a/src/views/projectManagement/Management/index.vue b/src/views/projectManagement/Management/index.vue
new file mode 100644
index 0000000..1a48db5
--- /dev/null
+++ b/src/views/projectManagement/Management/index.vue
@@ -0,0 +1,333 @@
+<template>
+  <div class="app-container">
+    <SearchPanel
+      v-model="queryParams"
+      :schema="searchSchema"
+      @search="handleQuery"
+      @reset="resetQuery"
+    >
+      <template #billStatus="{ item }">
+        <el-select v-model="queryParams[item.prop]" placeholder="璇烽�夋嫨鍗曟嵁鐘舵��" clearable style="width: 100%">
+          <el-option v-for="dict in bill_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+        </el-select>
+      </template>
+      <template #auditStatus="{ item }">
+        <el-select v-model="queryParams[item.prop]" placeholder="璇烽�夋嫨璁″垝鐘舵��" clearable style="width: 100%">
+          <el-option v-for="dict in project_management" :key="dict.value" :label="dict.label" :value="dict.value" />
+        </el-select>
+      </template>
+      <template #projectStage="{ item }">
+        <el-select v-model="queryParams[item.prop]" placeholder="璇烽�夋嫨瀹℃牳鐘舵��" clearable style="width: 100%">
+          <el-option v-for="dict in plan_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+        </el-select>
+      </template>
+    </SearchPanel>
+
+    <div class="table-container">
+      <div class="table-actions">
+        <el-button style="background-color: #002FA7; color: #fff" @click="handleAdd">鏂板</el-button>
+        <!-- <el-dropdown split-button type="default" @command="handleGenerateBill" style="margin-left: 10px;">
+          鐢熸垚鍗曟嵁
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item command="1">鐢熸垚鍗曟嵁1</el-dropdown-item>
+              <el-dropdown-item command="2">鐢熸垚鍗曟嵁2</el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown> -->
+        <el-button @click="handleSubmit">鎻愪氦</el-button>
+        <el-button @click="handleAudit">瀹℃牳</el-button>
+        <el-button @click="handleReverseAudit">鍙嶅鏍�</el-button>
+        <el-button @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+
+      <PIMTable
+        :column="columns"
+        :tableData="tableData"
+        :page="pagination"
+        :tableLoading="loading"
+        :isSelection="true"
+        @selection-change="handleSelectionChange"
+        @pagination="handlePagination"
+      >
+        <template #auditStatus="{ row }">
+          <dict-tag :options="project_management" :value="row.auditStatus" />
+        </template>
+        <template #projectStage="{ row }">
+          <dict-tag :options="plan_status" :value="row.projectStage" />
+        </template>
+        <template #action="{ row }">
+          <el-button link type="primary" @click="handleEdit(row)">缂栬緫</el-button>
+          <el-button link type="primary" @click="handleProgressReport(row)">杩涘害姹囨姤</el-button>
+          <el-button link type="primary" @click="handleDiscussProgress(row)">娲借皥杩涘睍</el-button>
+          <el-button link type="primary" @click="handleDetail(row)">璇︽儏</el-button>
+        </template>
+      </PIMTable>
+    </div>
+
+    <FormDia ref="formDiaRef" @completed="getList" />
+  </div>
+</template>
+
+<script setup name="ProjectManagement">
+import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
+import SearchPanel from '@/components/SearchPanel/index.vue'
+import PIMTable from '@/components/PIMTable/PIMTable.vue'
+import FormDia from './components/formDia.vue'
+import {
+  listProject,
+  delProject,
+  submitProject,
+  auditProject,
+  reverseAuditProject
+} from '@/api/projectManagement/project'
+import { ElMessage, ElMessageBox } from 'element-plus'
+
+const { proxy } = getCurrentInstance()
+const { bill_status, project_management, plan_status } = proxy.useDict('bill_status', 'project_management', 'plan_status')
+
+const loading = ref(false)
+const ids = ref([])
+const tableData = ref([])
+const formDiaRef = ref()
+
+const data = reactive({
+  queryParams: {
+    projectNameOrCode: undefined,
+    customerName: undefined,
+    billStatus: undefined,
+    projectStage: undefined,
+    auditStatus: undefined,
+    salesperson: undefined,
+    pageNum: 1,
+    pageSize: 10
+  },
+  pagination: {
+    current: 1,
+    size: 10,
+    total: 0,
+    layout: 'total, sizes, prev, pager, next, jumper'
+  }
+})
+
+const { queryParams, pagination } = toRefs(data)
+
+const searchSchema = [
+  { prop: 'projectNameOrCode', label: '椤圭洰鍚嶇О/缂栧彿', type: 'input', placeholder: '璇疯緭鍏ラ」鐩悕绉�/缂栧彿' },
+  { prop: 'customerName', label: '瀹㈡埛鍚嶇О', type: 'input', placeholder: '璇疯緭鍏ュ鎴峰悕绉�' },
+  { prop: 'billStatus', label: '鍗曟嵁鐘舵��', slot: 'billStatus' },
+  { prop: 'projectStage', label: '璁″垝鐘舵��', slot: 'projectStage' },
+  { prop: 'auditStatus', label: '瀹℃牳鐘舵��', slot: 'auditStatus' },
+  { prop: 'salesperson', label: '涓氬姟浜哄憳', type: 'input', placeholder: '璇疯緭鍏ヤ笟鍔′汉鍛�' }
+]
+
+const columns = [
+  { label: '鍗曟嵁缂栧彿', prop: 'billNo', align: 'center', width: '150' },
+  { label: '椤圭洰鍚嶇О', prop: 'projectName', align: 'center' },
+  { label: '瀹℃牳鐘舵��', prop: 'auditStatus', align: 'center', dataType: 'slot', slot: 'auditStatus' },
+  { label: '瀹㈡埛鍚嶇О', prop: 'customerName', align: 'center' },
+  { label: '绔嬮」鏃ユ湡', prop: 'setupDate', align: 'center', width: '120' },
+  { label: '椤圭洰鏉ユ簮', prop: 'projectSource', align: 'center' },
+  { label: '椤圭洰鍒嗙被', prop: 'projectClassification', align: 'center' },
+  { label: '鎿嶄綔', prop: 'action', align: 'center', width: '250', dataType: 'slot', slot: 'action', fixed: 'right' }
+]
+
+function getList() {
+  loading.value = true
+  const params = {
+    noOrName: queryParams.value.projectNameOrCode,
+    clientName: queryParams.value.customerName,
+    salesmanName: queryParams.value.salesperson,
+    reviewStatus: queryParams.value.auditStatus,
+    stage: queryParams.value.projectStage,
+    current: queryParams.value.pageNum,
+    size: queryParams.value.pageSize
+  }
+  listProject(params)
+    .then(response => {
+      const records = response?.data?.records || response?.rows || response?.records || []
+      const billFilter = queryParams.value.billStatus
+      const filtered = billFilter === undefined || billFilter === null || billFilter === ''
+        ? records
+        : records.filter(r => String(r.billStatus ?? r.status) === String(billFilter))
+      tableData.value = filtered.map(r => ({
+        id: r.id,
+        billNo: r.no ?? r.billNo,
+        projectName: r.title ?? r.projectName,
+        billStatus: r.billStatus ?? r.status,
+        auditStatus: r.reviewStatus ?? r.auditStatus,
+        projectStage: r.stage ?? r.projectStage,
+        customerName: r.clientName ?? r.customerName,
+        parentProject: r.parentTitle ?? r.parentName ?? r.parentProject,
+        setupDate: r.establishTime ?? r.setupDate,
+        projectType: r.planName ?? r.projectType,
+        projectSource: r.source ?? r.projectSource,
+        projectClassification: r.departmentName ?? r.projectClassification,
+        raw: r
+      }))
+      pagination.value.total = response?.total || response?.data?.total || 0
+    })
+    .finally(() => {
+      loading.value = false
+    })
+}
+
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  pagination.value.current = 1
+  getList()
+}
+
+function resetQuery() {
+  queryParams.value = {
+    projectNameOrCode: undefined,
+    customerName: undefined,
+    billStatus: undefined,
+    projectStage: undefined,
+    auditStatus: undefined,
+    salesperson: undefined,
+    pageNum: 1,
+    pageSize: 10
+  }
+  handleQuery()
+}
+
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.id)
+}
+
+function handlePagination({ page, limit }) {
+  queryParams.value.pageNum = page
+  queryParams.value.pageSize = limit
+  pagination.value.current = page
+  pagination.value.size = limit
+  getList()
+}
+
+function handleAdd() {
+  formDiaRef.value?.openDialog({ operationType: 'add' })
+}
+
+function handleDelete() {
+  const delIds = ids.value
+  if (delIds.length === 0) {
+    ElMessage.warning('璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁椤�')
+    return
+  }
+  ElMessageBox.confirm('鏄惁纭鍒犻櫎鎵�閫夋暟鎹」?', '璀﹀憡', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  })
+    .then(() => delProject(delIds))
+    .then(() => {
+      getList()
+      ElMessage.success('鍒犻櫎鎴愬姛')
+    })
+    .catch(() => {})
+}
+
+function handleSubmit() {
+  const submitIds = ids.value
+  if (submitIds.length === 0) {
+    ElMessage.warning('璇烽�夋嫨瑕佹彁浜ょ殑鏁版嵁椤�')
+    return
+  }
+  ElMessageBox.confirm('鏄惁纭鎻愪氦鎵�閫夋暟鎹」?', '鎻愮ず', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  })
+    .then(async () => {
+      await Promise.all(submitIds.map(id => submitProject({ id })))
+    })
+    .then(() => {
+      getList()
+      ElMessage.success('鎻愪氦鎴愬姛')
+    })
+    .catch(() => {})
+}
+
+function handleAudit() {
+  const auditIds = ids.value
+  if (auditIds.length === 0) {
+    ElMessage.warning('璇烽�夋嫨瑕佸鏍哥殑鏁版嵁椤�')
+    return
+  }
+  ElMessageBox.confirm('鏄惁纭瀹℃牳鎵�閫夋暟鎹」?', '鎻愮ず', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  })
+    .then(async () => {
+      await Promise.all(auditIds.map(id => auditProject({ id })))
+    })
+    .then(() => {
+      getList()
+      ElMessage.success('瀹℃牳鎴愬姛')
+    })
+    .catch(() => {})
+}
+
+function handleReverseAudit() {
+  const reverseAuditIds = ids.value
+  if (reverseAuditIds.length === 0) {
+    ElMessage.warning('璇烽�夋嫨瑕佸弽瀹℃牳鐨勬暟鎹」')
+    return
+  }
+  ElMessageBox.confirm('鏄惁纭鍙嶅鏍告墍閫夋暟鎹」?', '鎻愮ず', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  })
+    .then(async () => {
+      await Promise.all(reverseAuditIds.map(id => reverseAuditProject({ id })))
+    })
+    .then(() => {
+      getList()
+      ElMessage.success('鍙嶅鏍告垚鍔�')
+    })
+    .catch(() => {})
+}
+
+function handleGenerateBill(command) {
+  ElMessage.info(`鐢熸垚鍗曟嵁: ${command}`)
+}
+
+function handleProgressReport(row) {
+  formDiaRef.value?.openDialog({ operationType: 'view', row })
+}
+
+function handleDiscussProgress(row) {
+  formDiaRef.value?.openDialog({ operationType: 'view', row })
+}
+
+function handleDetail(row) {
+  formDiaRef.value?.openDialog({ operationType: 'view', row })
+}
+
+function handleEdit(row) {
+  formDiaRef.value?.openDialog({ operationType: 'edit', row })
+}
+
+onMounted(() => {
+  getList()
+})
+</script>
+
+<style scoped lang="scss">
+.app-container {
+  padding: 20px;
+}
+.table-container {
+  background-color: #fff;
+  padding: 20px;
+  border-radius: 4px;
+}
+.table-actions {
+  margin-bottom: 15px;
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+</style>

--
Gitblit v1.9.3