暂存
This commit is contained in:
@@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<!-- 背景视频 -->
|
<!-- 背景视频 -->
|
||||||
<video src="../../public/登陆界面背景.mp4" autoplay muted loop class="bg-video"></video>
|
<video src="/登陆界面背景.mp4" autoplay muted loop class="bg-video"></video>
|
||||||
<div class="video-overlay"></div>
|
<div class="video-overlay"></div>
|
||||||
|
|
||||||
<!-- 登录卡片 -->
|
<!-- 登录卡片 -->
|
||||||
<el-card class="login-card" shadow="always">
|
<el-card class="login-card" shadow="always">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<img src="../../public/logo.png" alt="logo" class="login-logo">
|
<img src="/logo.png" alt="logo" class="login-logo">
|
||||||
<h2>蜜雪冰城管理系统</h2>
|
<h2>蜜雪冰城管理系统</h2>
|
||||||
<p class="subtitle">请输入您的账号信息</p>
|
<p class="subtitle">请输入您的账号信息</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,13 +16,16 @@ import { hasPermission, getUserInfo } from '../store/user'
|
|||||||
|
|
||||||
const search = ref('')
|
const search = ref('')
|
||||||
const select = ref('1')
|
const select = ref('1')
|
||||||
const dateRange = ref([])
|
const filterType = ref('')
|
||||||
|
const filterStatus = ref('')
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const searchResults = ref([])
|
const searchResults = ref([])
|
||||||
const showSearchResults = ref(false)
|
const showSearchResults = ref(false)
|
||||||
const showAddForm = ref(false)
|
const showAddForm = ref(false)
|
||||||
const isEditMode = ref(false)
|
const isEditMode = ref(false)
|
||||||
const currentContractId = ref(null)
|
const currentContractId = ref(null)
|
||||||
|
const showDetailDialog = ref(false)
|
||||||
|
const currentDetail = ref(null)
|
||||||
const customerList = ref([])
|
const customerList = ref([])
|
||||||
const employeeList = ref([])
|
const employeeList = ref([])
|
||||||
const supplierList = ref([])
|
const supplierList = ref([])
|
||||||
@@ -30,6 +33,7 @@ const supplierList = ref([])
|
|||||||
// 分页相关
|
// 分页相关
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10)
|
||||||
|
const total = ref(0)
|
||||||
|
|
||||||
// 采购经理只能操作采购合同,招商经理只能操作加盟合同(提前定义,供 form 初始化使用)
|
// 采购经理只能操作采购合同,招商经理只能操作加盟合同(提前定义,供 form 初始化使用)
|
||||||
const isProcurementManager = computed(() => getUserInfo()?.departmentName === 'procurement_manager')
|
const isProcurementManager = computed(() => getUserInfo()?.departmentName === 'procurement_manager')
|
||||||
@@ -50,7 +54,7 @@ const form = reactive({
|
|||||||
effective_date: '',
|
effective_date: '',
|
||||||
expiry_date: '',
|
expiry_date: '',
|
||||||
amount: 0,
|
amount: 0,
|
||||||
status: '生效中',
|
status: '生效',
|
||||||
remark: ''
|
remark: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -59,30 +63,19 @@ onMounted(() => {
|
|||||||
fetchOptions()
|
fetchOptions()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听搜索结果变化,重置页码
|
// 监听筛选变化(与 user.vue 一致)
|
||||||
watch(searchResults, () => {
|
watch([filterType, filterStatus], () => {
|
||||||
currentPage.value = 1
|
currentPage.value = 1
|
||||||
|
handleSearch()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 分页后的数据
|
// 分页后的数据(服务端已分页,searchResults 即为当前页数据)
|
||||||
const filteredResults = computed(() => {
|
const paginatedData = computed(() => searchResults.value)
|
||||||
if (!isFranchiseManager.value && !isProcurementManager.value) return searchResults.value
|
|
||||||
return searchResults.value.filter(row => {
|
|
||||||
if (row.type === 'supply' && isProcurementManager.value) return true
|
|
||||||
if (row.type === 'franchise' && isFranchiseManager.value) return true
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const paginatedData = computed(() => {
|
// 页码变化(服务端分页:重新请求后端)
|
||||||
const start = (currentPage.value - 1) * pageSize.value
|
|
||||||
const end = start + pageSize.value
|
|
||||||
return filteredResults.value.slice(start, end)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 页码变化
|
|
||||||
const handleCurrentChange = (val) => {
|
const handleCurrentChange = (val) => {
|
||||||
currentPage.value = val
|
currentPage.value = val
|
||||||
|
fetchData(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取客户、员工、供应商和用户列表供下拉选择
|
// 获取客户、员工、供应商和用户列表供下拉选择
|
||||||
@@ -106,12 +99,22 @@ const fetchOptions = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取合同列表
|
// 获取合同列表(服务端分页)
|
||||||
const fetchData = async () => {
|
const fetchData = async (page) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const res = await getContractList()
|
const params = {
|
||||||
|
page: page || currentPage.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
}
|
||||||
|
const res = await getContractList(params)
|
||||||
if (res.code === 0 || res.code === 200) {
|
if (res.code === 0 || res.code === 200) {
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -124,40 +127,74 @@ const handleSearch = async () => {
|
|||||||
cancelAdd()
|
cancelAdd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentPage.value = 1
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
const params = {}
|
const params = {
|
||||||
if (select.value === '1') {
|
page: 1,
|
||||||
params.id = Number(search.value)
|
pageSize: pageSize.value
|
||||||
} else if (select.value === '2') {
|
|
||||||
params.contract_name = search.value
|
|
||||||
}
|
}
|
||||||
if (dateRange.value && dateRange.value.length === 2) {
|
// 只在有搜索内容时才添加搜索参数(与 user.vue 一致)
|
||||||
params.effective_date_start = formatDate(dateRange.value[0])
|
if (search.value) {
|
||||||
params.effective_date_end = formatDate(dateRange.value[1])
|
if (select.value === '1') {
|
||||||
|
params.id = Number(search.value)
|
||||||
|
} else if (select.value === '2') {
|
||||||
|
params.contract_name = search.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filterType.value) {
|
||||||
|
params.type = filterType.value
|
||||||
|
}
|
||||||
|
if (filterStatus.value) {
|
||||||
|
params.status = filterStatus.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await getContractList(params)
|
try {
|
||||||
if (res.code === 0 || res.code === 200) {
|
const res = await getContractList(params)
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.code === 0 || res.code === 200) {
|
||||||
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('[contract] handleSearch 响应异常:', res)
|
||||||
|
searchResults.value = []
|
||||||
|
total.value = 0
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[contract] handleSearch 请求失败:', e)
|
||||||
|
searchResults.value = []
|
||||||
|
total.value = 0
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 日期变更处理
|
|
||||||
const handleDateChange = () => {
|
|
||||||
handleSearch()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重置搜索
|
// 重置搜索
|
||||||
const resetSearch = () => {
|
const resetSearch = () => {
|
||||||
search.value = ''
|
search.value = ''
|
||||||
select.value = '1'
|
select.value = '1'
|
||||||
dateRange.value = []
|
filterType.value = ''
|
||||||
|
filterStatus.value = ''
|
||||||
|
currentPage.value = 1
|
||||||
fetchData()
|
fetchData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 双击行查看详情
|
||||||
|
const handleRowDblClick = (row) => {
|
||||||
|
currentDetail.value = { ...row }
|
||||||
|
showDetailDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭详情弹窗
|
||||||
|
const closeDetail = () => {
|
||||||
|
showDetailDialog.value = false
|
||||||
|
currentDetail.value = null
|
||||||
|
}
|
||||||
|
|
||||||
// 新增合同
|
// 新增合同
|
||||||
const addContract = () => {
|
const addContract = () => {
|
||||||
resetForm()
|
resetForm()
|
||||||
@@ -257,7 +294,7 @@ const resetForm = () => {
|
|||||||
effective_date: '',
|
effective_date: '',
|
||||||
expiry_date: '',
|
expiry_date: '',
|
||||||
amount: 0,
|
amount: 0,
|
||||||
status: '生效中',
|
status: '生效',
|
||||||
remark: ''
|
remark: ''
|
||||||
})
|
})
|
||||||
isEditMode.value = false
|
isEditMode.value = false
|
||||||
@@ -268,9 +305,7 @@ const resetForm = () => {
|
|||||||
const getStatusType = (status) => {
|
const getStatusType = (status) => {
|
||||||
const map = {
|
const map = {
|
||||||
'草稿': 'info',
|
'草稿': 'info',
|
||||||
'生效中': 'success',
|
|
||||||
'生效': 'success',
|
'生效': 'success',
|
||||||
'完成': 'success',
|
|
||||||
'已完成': 'success',
|
'已完成': 'success',
|
||||||
'作废': 'danger'
|
'作废': 'danger'
|
||||||
}
|
}
|
||||||
@@ -339,8 +374,8 @@ const canDeleteRow = (row) => {
|
|||||||
@keyup.enter="handleSearch">
|
@keyup.enter="handleSearch">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
||||||
<el-option label="编号" value="1" />
|
<el-option label="合同编号" value="1" />
|
||||||
<el-option label="名称" value="2" />
|
<el-option label="合同名称" value="2" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
@@ -358,8 +393,17 @@ const canDeleteRow = (row) => {
|
|||||||
<div class="filter-row">
|
<div class="filter-row">
|
||||||
<span class="filter-label">筛选条件:</span>
|
<span class="filter-label">筛选条件:</span>
|
||||||
|
|
||||||
<el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="生效日期"
|
<el-select v-model="filterType" placeholder="合同类型" clearable style="width: 150px; margin-left: 10px;">
|
||||||
end-placeholder="到期日期" style="margin-left: 10px;" @change="handleDateChange" />
|
<el-option label="加盟合同" value="franchise" />
|
||||||
|
<el-option label="采购合同" value="supply" />
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<el-select v-model="filterStatus" placeholder="合同状态" clearable style="width: 150px; margin-left: 10px;">
|
||||||
|
<el-option label="草稿" value="草稿" />
|
||||||
|
<el-option label="生效" value="生效" />
|
||||||
|
<el-option label="已完成" value="已完成" />
|
||||||
|
<el-option label="作废" value="作废" />
|
||||||
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -375,27 +419,17 @@ const canDeleteRow = (row) => {
|
|||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<span class="total-count">共找到 {{ searchResults.length }} 条合同</span>
|
<span class="total-count">共找到 {{ total }} 条合同</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="paginatedData" border style="width: 100%">
|
<el-table :data="paginatedData" border style="width: 100%" @row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
||||||
<el-table-column prop="id" label="编号" width="70" />
|
<el-table-column prop="id" label="合同编号" width="90" />
|
||||||
<el-table-column prop="contract_name" label="合同名称" min-width="180" />
|
<el-table-column prop="contract_name" label="合同名称" min-width="200" />
|
||||||
<el-table-column prop="type" label="类型" width="90">
|
<el-table-column prop="type" label="类型" width="90">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag :type="row.type === 'franchise' ? 'success' : 'warning'">{{ row.type === 'franchise' ? '加盟' : '采购' }}</el-tag>
|
<el-tag :type="row.type === 'franchise' ? 'success' : 'warning'">{{ row.type === 'franchise' ? '加盟' : '采购' }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="customer_name" label="客户" width="100">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.customer_name || '-' }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="supplier_name" label="供应商" width="100">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.supplier_name || '-' }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="employee_name" label="业务员" width="90">
|
<el-table-column prop="employee_name" label="业务员" width="90">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.employee_name || '-' }}
|
{{ row.employee_name || '-' }}
|
||||||
@@ -411,16 +445,6 @@ const canDeleteRow = (row) => {
|
|||||||
<el-tag :type="getStatusType(row.status)">{{ row.status }}</el-tag>
|
<el-tag :type="getStatusType(row.status)">{{ row.status }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="effective_date" label="生效日期" width="110">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ formatDate(row.effective_date) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="expiry_date" label="到期日期" width="110">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ formatDate(row.expiry_date) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="160" fixed="right" v-if="canOperate">
|
<el-table-column label="操作" width="160" fixed="right" v-if="canOperate">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button link type="primary" @click="editContract(row)" v-if="canEditRow(row)">编辑</el-button>
|
<el-button link type="primary" @click="editContract(row)" v-if="canEditRow(row)">编辑</el-button>
|
||||||
@@ -434,7 +458,7 @@ const canDeleteRow = (row) => {
|
|||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:total="filteredResults.length"
|
:total="total"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
prev-text="上一页"
|
prev-text="上一页"
|
||||||
next-text="下一页"
|
next-text="下一页"
|
||||||
@@ -444,6 +468,35 @@ const canDeleteRow = (row) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 合同详情弹窗 -->
|
||||||
|
<el-dialog v-model="showDetailDialog" title="合同详情" width="700px" @close="closeDetail">
|
||||||
|
<div v-if="currentDetail" class="detail-content">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="合同编号">{{ currentDetail.id }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="合同名称">{{ currentDetail.contract_name }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="合同类型">
|
||||||
|
<el-tag :type="currentDetail.type === 'franchise' ? 'success' : 'warning'">{{ currentDetail.type === 'franchise' ? '加盟合同' : '采购合同' }}</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态">
|
||||||
|
<el-tag :type="getStatusType(currentDetail.status)">{{ currentDetail.status }}</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="客户">{{ currentDetail.customer_name || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="供应商">{{ currentDetail.supplier_name || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="业务员">{{ currentDetail.employee_name || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="负责人">{{ currentDetail.responsible_user_name || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="金额">¥{{ currentDetail.amount?.toLocaleString() }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="生效日期">{{ formatDate(currentDetail.effective_date) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="到期日期">{{ formatDate(currentDetail.expiry_date) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="合同内容" :span="2">{{ currentDetail.contract_content || '无' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ currentDetail.remark || '无' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="closeDetail">关闭</el-button>
|
||||||
|
<el-button type="primary" @click="(() => { const d = currentDetail; closeDetail(); editContract(d) })()" v-if="canOperate">编辑</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 新增/编辑表单 -->
|
<!-- 新增/编辑表单 -->
|
||||||
<div v-if="showAddForm" class="contract-form" style="margin-top: 20px;">
|
<div v-if="showAddForm" class="contract-form" style="margin-top: 20px;">
|
||||||
<el-divider content-position="left">{{ isEditMode ? '编辑合同' : '新增合同' }}</el-divider>
|
<el-divider content-position="left">{{ isEditMode ? '编辑合同' : '新增合同' }}</el-divider>
|
||||||
@@ -514,7 +567,7 @@ const canDeleteRow = (row) => {
|
|||||||
<el-form-item label="状态" required>
|
<el-form-item label="状态" required>
|
||||||
<el-select v-model="form.status" style="width: 100%;">
|
<el-select v-model="form.status" style="width: 100%;">
|
||||||
<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-option label="完成" value="完成" />
|
<el-option label="完成" value="完成" />
|
||||||
<el-option label="作废" value="作废" />
|
<el-option label="作废" value="作废" />
|
||||||
@@ -603,4 +656,12 @@ const canDeleteRow = (row) => {
|
|||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
border-top: 1px solid #eee;
|
border-top: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clickable-row {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -38,6 +38,7 @@ const filterRegion = ref([])
|
|||||||
// 分页相关
|
// 分页相关
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10)
|
||||||
|
const total = ref(0)
|
||||||
|
|
||||||
// 只保留省市两级的地区数据
|
// 只保留省市两级的地区数据
|
||||||
const regionDataTwoLevel = computed(() => {
|
const regionDataTwoLevel = computed(() => {
|
||||||
@@ -50,28 +51,29 @@ const regionDataTwoLevel = computed(() => {
|
|||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
// 分页后的数据
|
// 分页后的数据(服务端已分页,searchResults 即为当前页数据)
|
||||||
const paginatedData = computed(() => {
|
const paginatedData = computed(() => searchResults.value)
|
||||||
const start = (currentPage.value - 1) * pageSize.value
|
|
||||||
const end = start + pageSize.value
|
|
||||||
return searchResults.value.slice(start, end)
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchData()
|
fetchData()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听搜索结果变化,重置页码
|
// 获取客户列表(服务端分页)
|
||||||
watch(searchResults, () => {
|
const fetchData = async (page) => {
|
||||||
currentPage.value = 1
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取客户列表
|
|
||||||
const fetchData = async () => {
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const res = await getCustomerList()
|
const params = {
|
||||||
|
page: page || currentPage.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
}
|
||||||
|
const res = await getCustomerList(params)
|
||||||
if (res.code === 0 || res.code === 200) {
|
if (res.code === 0 || res.code === 200) {
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -88,6 +90,8 @@ const handleSearch = async () => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const params = {
|
const params = {
|
||||||
|
page: currentPage.value,
|
||||||
|
pageSize: pageSize.value,
|
||||||
name: select.value === '1' ? search.value : undefined,
|
name: select.value === '1' ? search.value : undefined,
|
||||||
id: select.value === '2' ? Number(search.value) : undefined,
|
id: select.value === '2' ? Number(search.value) : undefined,
|
||||||
province: filterRegion.value?.[0] ? CodeToText[filterRegion.value[0]] : undefined,
|
province: filterRegion.value?.[0] ? CodeToText[filterRegion.value[0]] : undefined,
|
||||||
@@ -96,7 +100,13 @@ const handleSearch = async () => {
|
|||||||
const res = await getCustomerList(params)
|
const res = await getCustomerList(params)
|
||||||
if (seq !== searchSeq) return
|
if (seq !== searchSeq) return
|
||||||
if (res.code === 0 || res.code === 200) {
|
if (res.code === 0 || res.code === 200) {
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
} finally {
|
} finally {
|
||||||
@@ -215,9 +225,10 @@ const closeDetail = () => {
|
|||||||
currentDetail.value = null
|
currentDetail.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页码变化
|
// 页码变化(服务端分页:重新请求后端)
|
||||||
const handleCurrentChange = (val) => {
|
const handleCurrentChange = (val) => {
|
||||||
currentPage.value = val
|
currentPage.value = val
|
||||||
|
fetchData(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查权限
|
// 检查权限
|
||||||
@@ -237,8 +248,8 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
class="customer-search-with-select" @keyup.enter="handleSearch">
|
class="customer-search-with-select" @keyup.enter="handleSearch">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
||||||
<el-option label="姓名" value="1" />
|
<el-option label="客户姓名" value="1" />
|
||||||
<el-option label="编号" value="2" />
|
<el-option label="客户编号" value="2" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
@@ -278,11 +289,11 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<span class="total-count">共找到 {{ searchResults.length }} 条记录</span>
|
<span class="total-count">共找到 {{ total }} 条记录</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%" @row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%" @row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
||||||
<el-table-column prop="id" label="编号" width="80" />
|
<el-table-column prop="id" label="客户编号" width="90" />
|
||||||
<el-table-column prop="name" label="姓名" width="120" />
|
<el-table-column prop="name" label="姓名" width="120" />
|
||||||
<el-table-column prop="phone" label="电话" width="150" />
|
<el-table-column prop="phone" label="电话" width="150" />
|
||||||
<el-table-column label="地区" min-width="150">
|
<el-table-column label="地区" min-width="150">
|
||||||
@@ -306,7 +317,7 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:total="searchResults.length"
|
:total="total"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
prev-text="上一页"
|
prev-text="上一页"
|
||||||
next-text="下一页"
|
next-text="下一页"
|
||||||
@@ -326,7 +337,7 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="电话" required>
|
<el-form-item label="电话" required>
|
||||||
<el-input v-model="form.phone" maxlength="11"
|
<el-input v-model="form.phone" maxlength="11" oninput="this.value=this.value.replace(/\D/g,'')"
|
||||||
placeholder="请输入11位手机号" style="width: 100%" />
|
placeholder="请输入11位手机号" style="width: 100%" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|||||||
@@ -373,8 +373,8 @@ const showSalary = computed(() => ['总经理办公室', '财务部'].includes(g
|
|||||||
class="employee-search-with-select" @keyup.enter="handleSearch">
|
class="employee-search-with-select" @keyup.enter="handleSearch">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
||||||
<el-option label="ID" value="1" />
|
<el-option label="员工编号" value="1" />
|
||||||
<el-option label="姓名" value="2" />
|
<el-option label="员工姓名" value="2" />
|
||||||
<el-option label="部门" value="3" />
|
<el-option label="部门" value="3" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
@@ -413,7 +413,7 @@ const showSalary = computed(() => ['总经理办公室', '财务部'].includes(g
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%" @row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%" @row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
||||||
<el-table-column prop="id" label="ID" width="60" />
|
<el-table-column prop="id" label="员工编号" width="90" />
|
||||||
<el-table-column prop="name" label="姓名" width="80" />
|
<el-table-column prop="name" label="姓名" width="80" />
|
||||||
<el-table-column prop="gender" label="性别" width="60">
|
<el-table-column prop="gender" label="性别" width="60">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -531,7 +531,7 @@ const showSalary = computed(() => ['总经理办公室', '财务部'].includes(g
|
|||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="联系电话">
|
<el-form-item label="联系电话">
|
||||||
<el-input v-model="form.phone" placeholder="请输入手机号" />
|
<el-input v-model="form.phone" placeholder="请输入手机号" type="tel" maxlength="11" oninput="this.value=this.value.replace(/\D/g,'')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@@ -623,7 +623,7 @@ const showSalary = computed(() => ['总经理办公室', '财务部'].includes(g
|
|||||||
<el-dialog v-model="showDetailDialog" title="员工详情" width="650px" @close="closeDetail">
|
<el-dialog v-model="showDetailDialog" title="员工详情" width="650px" @close="closeDetail">
|
||||||
<div v-if="currentDetail" class="detail-content">
|
<div v-if="currentDetail" class="detail-content">
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="员工ID">{{ currentDetail.id }}</el-descriptions-item>
|
<el-descriptions-item label="员工编号">{{ currentDetail.id }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="姓名">{{ currentDetail.name }}</el-descriptions-item>
|
<el-descriptions-item label="姓名">{{ currentDetail.name }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="性别">
|
<el-descriptions-item label="性别">
|
||||||
<span :style="{ color: currentDetail.gender === '女' ? '#e6a23c' : '#409eff' }">{{ currentDetail.gender }}</span>
|
<span :style="{ color: currentDetail.gender === '女' ? '#e6a23c' : '#409eff' }">{{ currentDetail.gender }}</span>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="home-container">
|
<div class="home-container">
|
||||||
<!-- 顶部视频横幅 -->
|
<!-- 顶部视频横幅 -->
|
||||||
<div class="video-banner">
|
<div class="video-banner">
|
||||||
<video src="../../public/首页顶图.mp4" autoplay muted loop class="bg-video"></video>
|
<video src="/首页顶图.mp4" autoplay muted loop class="bg-video"></video>
|
||||||
<div class="video-overlay">
|
<div class="video-overlay">
|
||||||
<h2 class="banner-title">欢迎使用蜜雪冰城管理系统</h2>
|
<h2 class="banner-title">欢迎使用蜜雪冰城管理系统</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<div class="intro-content">
|
<div class="intro-content">
|
||||||
<div class="pic-wrapper">
|
<div class="pic-wrapper">
|
||||||
<img src="../../public/mixue.png" alt="雪王" class="xuewang-img">
|
<img src="/mixue.png" alt="雪王" class="xuewang-img">
|
||||||
</div>
|
</div>
|
||||||
<div class="txt-wrapper">
|
<div class="txt-wrapper">
|
||||||
<div class="quote">
|
<div class="quote">
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const checkPermission = (resource, action) => {
|
|||||||
>
|
>
|
||||||
<!-- 左侧 Logo -->
|
<!-- 左侧 Logo -->
|
||||||
<el-menu-item index="" class="logo-item">
|
<el-menu-item index="" class="logo-item">
|
||||||
<img src="../../public/logo.png" alt="logo" class="logo-img">
|
<img src="/logo.png" alt="logo" class="logo-img">
|
||||||
<h1 class="logo-title">蜜雪冰城管理系统</h1>
|
<h1 class="logo-title">蜜雪冰城管理系统</h1>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
|
|||||||
@@ -39,14 +39,13 @@ const supplierList = ref([])
|
|||||||
// 分页相关
|
// 分页相关
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10)
|
||||||
|
const total = ref(0)
|
||||||
|
|
||||||
// 产品类型映射
|
// 产品类型映射
|
||||||
const productTypeMap = {
|
const productTypeMap = {
|
||||||
raw_material: '原材料',
|
'茶饮原料': '茶饮原料',
|
||||||
packaging: '包装材料',
|
'包装物料': '包装物料',
|
||||||
equipment: '设备器具',
|
'设备器具': '设备器具'
|
||||||
cleaning: '清洁用品',
|
|
||||||
promote: '宣传物料'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -67,24 +66,25 @@ watch(filterType, () => {
|
|||||||
handleSearch()
|
handleSearch()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听搜索结果变化,重置页码
|
// 分页后的数据(服务端已分页,searchResults 即为当前页数据)
|
||||||
watch(searchResults, () => {
|
const paginatedData = computed(() => searchResults.value)
|
||||||
currentPage.value = 1
|
|
||||||
})
|
|
||||||
|
|
||||||
// 分页后的数据
|
// 获取产品列表(服务端分页)
|
||||||
const paginatedData = computed(() => {
|
const fetchData = async (page) => {
|
||||||
const start = (currentPage.value - 1) * pageSize.value
|
|
||||||
const end = start + pageSize.value
|
|
||||||
return searchResults.value.slice(start, end)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取产品列表
|
|
||||||
const fetchData = async () => {
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const res = await getProductsList()
|
const params = {
|
||||||
|
page: page || currentPage.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
}
|
||||||
|
const res = await getProductsList(params)
|
||||||
if (res.code === 0 || res.code === 200) {
|
if (res.code === 0 || res.code === 200) {
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -99,6 +99,8 @@ const handleSearch = async () => {
|
|||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const params = {
|
const params = {
|
||||||
|
page: currentPage.value,
|
||||||
|
pageSize: pageSize.value,
|
||||||
type: filterType.value || undefined
|
type: filterType.value || undefined
|
||||||
}
|
}
|
||||||
if (select.value === '1') {
|
if (select.value === '1') {
|
||||||
@@ -110,7 +112,13 @@ const handleSearch = async () => {
|
|||||||
}
|
}
|
||||||
const res = await getProductsList(params)
|
const res = await getProductsList(params)
|
||||||
if (res.code === 0 || res.code === 200) {
|
if (res.code === 0 || res.code === 200) {
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -236,18 +244,17 @@ const closeDetail = () => {
|
|||||||
// 产品类型标签样式
|
// 产品类型标签样式
|
||||||
const getTypeTag = (type) => {
|
const getTypeTag = (type) => {
|
||||||
const map = {
|
const map = {
|
||||||
raw_material: '',
|
'茶饮原料': '',
|
||||||
packaging: 'success',
|
'包装物料': 'success',
|
||||||
equipment: 'warning',
|
'设备器具': 'warning'
|
||||||
cleaning: 'info',
|
|
||||||
promote: 'danger'
|
|
||||||
}
|
}
|
||||||
return map[type] || 'info'
|
return map[type] || 'info'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页码变化
|
// 页码变化(服务端分页:重新请求后端)
|
||||||
const handleCurrentChange = (val) => {
|
const handleCurrentChange = (val) => {
|
||||||
currentPage.value = val
|
currentPage.value = val
|
||||||
|
fetchData(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查权限
|
// 检查权限
|
||||||
@@ -267,8 +274,8 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
class="products-search-with-select" @keyup.enter="handleSearch">
|
class="products-search-with-select" @keyup.enter="handleSearch">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
||||||
<el-option label="ID" value="1" />
|
<el-option label="产品编号" value="1" />
|
||||||
<el-option label="名称" value="2" />
|
<el-option label="产品名称" value="2" />
|
||||||
<el-option label="供应商" value="3" />
|
<el-option label="供应商" value="3" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
@@ -286,11 +293,9 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
<div class="filter-row">
|
<div class="filter-row">
|
||||||
<span class="filter-label">筛选条件:</span>
|
<span class="filter-label">筛选条件:</span>
|
||||||
<el-select v-model="filterType" placeholder="产品类型" clearable style="width: 140px; margin-right: 12px;">
|
<el-select v-model="filterType" placeholder="产品类型" clearable style="width: 140px; margin-right: 12px;">
|
||||||
<el-option label="原材料" value="raw_material" />
|
<el-option label="茶饮原料" value="茶饮原料" />
|
||||||
<el-option label="包装材料" value="packaging" />
|
<el-option label="包装物料" value="包装物料" />
|
||||||
<el-option label="设备器具" value="equipment" />
|
<el-option label="设备器具" value="设备器具" />
|
||||||
<el-option label="清洁用品" value="cleaning" />
|
|
||||||
<el-option label="宣传物料" value="promote" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -306,12 +311,12 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<span class="total-count">共找到 {{ searchResults.length }} 条记录</span>
|
<span class="total-count">共找到 {{ total }} 条记录</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%"
|
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%"
|
||||||
@row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
@row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
||||||
<el-table-column prop="id" label="ID" width="70" />
|
<el-table-column prop="id" label="产品编号" width="90" />
|
||||||
<el-table-column prop="name" label="产品名称" min-width="120" />
|
<el-table-column prop="name" label="产品名称" min-width="120" />
|
||||||
<el-table-column prop="type" label="产品类型" width="110">
|
<el-table-column prop="type" label="产品类型" width="110">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -342,7 +347,7 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:total="searchResults.length"
|
:total="total"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
prev-text="上一页"
|
prev-text="上一页"
|
||||||
next-text="下一页"
|
next-text="下一页"
|
||||||
@@ -362,11 +367,9 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
|
|
||||||
<el-form-item label="产品类型" required>
|
<el-form-item label="产品类型" required>
|
||||||
<el-select v-model="form.type" placeholder="请选择产品类型" style="width: 100%;">
|
<el-select v-model="form.type" placeholder="请选择产品类型" style="width: 100%;">
|
||||||
<el-option label="原材料" value="raw_material" />
|
<el-option label="茶饮原料" value="茶饮原料" />
|
||||||
<el-option label="包装材料" value="packaging" />
|
<el-option label="包装物料" value="包装物料" />
|
||||||
<el-option label="设备器具" value="equipment" />
|
<el-option label="设备器具" value="设备器具" />
|
||||||
<el-option label="清洁用品" value="cleaning" />
|
|
||||||
<el-option label="宣传物料" value="promote" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ const showSearchResults = ref(false)
|
|||||||
const showAddForm = ref(false)
|
const showAddForm = ref(false)
|
||||||
const isEditMode = ref(false)
|
const isEditMode = ref(false)
|
||||||
const currentServiceId = ref(null)
|
const currentServiceId = ref(null)
|
||||||
|
const showDetailDialog = ref(false)
|
||||||
|
const currentDetail = ref(null)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const customerList = ref([])
|
const customerList = ref([])
|
||||||
const employeeList = ref([])
|
const employeeList = ref([])
|
||||||
@@ -39,6 +41,7 @@ const employeeList = ref([])
|
|||||||
// 分页相关
|
// 分页相关
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10)
|
||||||
|
const total = ref(0)
|
||||||
|
|
||||||
// 状态映射
|
// 状态映射
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
@@ -73,37 +76,31 @@ watch(() => form.handle_status, (val) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听筛选变化
|
// 监听筛选变化(与 user.vue 一致)
|
||||||
watch(filterStatus, () => {
|
watch(filterStatus, () => {
|
||||||
currentPage.value = 1
|
currentPage.value = 1
|
||||||
handleSearch()
|
handleSearch()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听搜索结果变化,重置页码
|
// 分页后的数据(服务端已分页,searchResults 即为当前页数据)
|
||||||
watch(searchResults, () => {
|
const paginatedData = computed(() => searchResults.value)
|
||||||
currentPage.value = 1
|
|
||||||
})
|
|
||||||
|
|
||||||
const filteredResults = computed(() => {
|
// 获取售后列表(服务端分页)
|
||||||
if (!isOperationsManager.value) return searchResults.value
|
const fetchData = async (page) => {
|
||||||
return searchResults.value.filter(row => {
|
|
||||||
return row.responsible_user_id != null && Number(row.responsible_user_id) === Number(currentUserId.value)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// 分页后的数据
|
|
||||||
const paginatedData = computed(() => {
|
|
||||||
const start = (currentPage.value - 1) * pageSize.value
|
|
||||||
const end = start + pageSize.value
|
|
||||||
return filteredResults.value.slice(start, end)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取售后列表
|
|
||||||
const fetchData = async () => {
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const res = await getServiceList()
|
const params = {
|
||||||
|
page: page || currentPage.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
}
|
||||||
|
const res = await getServiceList(params)
|
||||||
if (res.code === 0 || res.code === 200) {
|
if (res.code === 0 || res.code === 200) {
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -116,22 +113,44 @@ const handleSearch = async () => {
|
|||||||
cancelAdd()
|
cancelAdd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentPage.value = 1
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const params = {
|
const params = {
|
||||||
|
page: 1,
|
||||||
|
pageSize: pageSize.value,
|
||||||
handle_status: filterStatus.value || undefined
|
handle_status: filterStatus.value || undefined
|
||||||
}
|
}
|
||||||
if (select.value === '1') {
|
// 只在有搜索内容时才添加搜索参数(与 user.vue 一致)
|
||||||
params.id = Number(search.value)
|
if (search.value) {
|
||||||
} else if (select.value === '2') {
|
if (select.value === '1') {
|
||||||
params.customer_id = search.value
|
params.id = Number(search.value)
|
||||||
} else if (select.value === '3') {
|
} else if (select.value === '2') {
|
||||||
params.feedback = search.value
|
params.customer_id = search.value
|
||||||
} else if (select.value === '4') {
|
} else if (select.value === '3') {
|
||||||
params.customer_name = search.value
|
params.feedback = search.value
|
||||||
|
} else if (select.value === '4') {
|
||||||
|
params.customer_name = search.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const res = await getServiceList(params)
|
try {
|
||||||
if (res.code === 0 || res.code === 200) {
|
const res = await getServiceList(params)
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.code === 0 || res.code === 200) {
|
||||||
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('[service] handleSearch 响应异常:', res)
|
||||||
|
searchResults.value = []
|
||||||
|
total.value = 0
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[service] handleSearch 请求失败:', e)
|
||||||
|
searchResults.value = []
|
||||||
|
total.value = 0
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -152,6 +171,18 @@ const clearSearch = () => {
|
|||||||
resetSearch()
|
resetSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 双击行查看详情
|
||||||
|
const handleRowDblClick = (row) => {
|
||||||
|
currentDetail.value = { ...row }
|
||||||
|
showDetailDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭详情弹窗
|
||||||
|
const closeDetail = () => {
|
||||||
|
showDetailDialog.value = false
|
||||||
|
currentDetail.value = null
|
||||||
|
}
|
||||||
|
|
||||||
// 清空表单
|
// 清空表单
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
form.customer_id = ''
|
form.customer_id = ''
|
||||||
@@ -253,9 +284,10 @@ const cancelAdd = () => {
|
|||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页码变化
|
// 页码变化(服务端分页:重新请求后端)
|
||||||
const handleCurrentChange = (val) => {
|
const handleCurrentChange = (val) => {
|
||||||
currentPage.value = val
|
currentPage.value = val
|
||||||
|
fetchData(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查权限
|
// 检查权限
|
||||||
@@ -287,8 +319,8 @@ const canDeleteRow = (row) => {
|
|||||||
class="service-search-with-select" @keyup.enter="handleSearch">
|
class="service-search-with-select" @keyup.enter="handleSearch">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
||||||
<el-option label="编号" value="1" />
|
<el-option label="售后编号" value="1" />
|
||||||
<el-option label="客户ID" value="2" />
|
<el-option label="客户编号" value="2" />
|
||||||
<el-option label="客户姓名" value="4" />
|
<el-option label="客户姓名" value="4" />
|
||||||
<el-option label="反馈内容" value="3" />
|
<el-option label="反馈内容" value="3" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -325,11 +357,11 @@ const canDeleteRow = (row) => {
|
|||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<span class="total-count">共找到 {{ searchResults.length }} 条记录</span>
|
<span class="total-count">共找到 {{ total }} 条记录</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%">
|
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%" @row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
||||||
<el-table-column prop="id" label="编号" width="70" />
|
<el-table-column prop="id" label="售后编号" width="90" />
|
||||||
<el-table-column prop="customer_name" label="客户" width="100">
|
<el-table-column prop="customer_name" label="客户" width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.customer_name || row.customer_id }}
|
{{ row.customer_name || row.customer_id }}
|
||||||
@@ -367,7 +399,7 @@ const canDeleteRow = (row) => {
|
|||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:total="filteredResults.length"
|
:total="total"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
prev-text="上一页"
|
prev-text="上一页"
|
||||||
next-text="下一页"
|
next-text="下一页"
|
||||||
@@ -377,6 +409,29 @@ const canDeleteRow = (row) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 售后详情弹窗 -->
|
||||||
|
<el-dialog v-model="showDetailDialog" title="售后详情" width="700px" @close="closeDetail">
|
||||||
|
<div v-if="currentDetail" class="detail-content">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="售后编号">{{ currentDetail.id }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="客户">{{ currentDetail.customer_name || currentDetail.customer_id }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="业务员">{{ currentDetail.employee_name || currentDetail.employee_id || '—' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="处理状态">
|
||||||
|
<el-tag :type="statusMap[currentDetail.handle_status]">{{ currentDetail.handle_status }}</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="售后日期">{{ formatDate(currentDetail.service_date) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="负责人">{{ currentDetail.responsible_user_name || '—' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="反馈内容" :span="2">{{ currentDetail.feedback || '无' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="处理方式" :span="2">{{ currentDetail.handle_method || '无' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ currentDetail.remark || '无' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="closeDetail">关闭</el-button>
|
||||||
|
<el-button type="primary" @click="(() => { const d = currentDetail; closeDetail(); editService(d) })()" v-if="canOperate">编辑</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 新增/编辑售后表单 -->
|
<!-- 新增/编辑售后表单 -->
|
||||||
<div v-if="showAddForm" class="service-info-label">
|
<div v-if="showAddForm" class="service-info-label">
|
||||||
<el-divider content-position="left">{{ isEditMode ? '编辑售后记录' : '新增售后' }}</el-divider>
|
<el-divider content-position="left">{{ isEditMode ? '编辑售后记录' : '新增售后' }}</el-divider>
|
||||||
@@ -490,4 +545,12 @@ const canDeleteRow = (row) => {
|
|||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
border-top: 1px solid #eee;
|
border-top: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clickable-row {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -37,9 +37,10 @@ const currentDetail = ref(null)
|
|||||||
// 分页相关
|
// 分页相关
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10)
|
||||||
|
const total = ref(0)
|
||||||
|
|
||||||
// 供应商类型
|
// 供应商类型
|
||||||
const supplierTypes = ['原材料', '包装', '设备']
|
const supplierTypes = ['原料', '包装', '设备']
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchData()
|
fetchData()
|
||||||
@@ -51,24 +52,25 @@ watch([filterType, filterStatus], () => {
|
|||||||
handleSearch()
|
handleSearch()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听搜索结果变化
|
// 分页后的数据(服务端已分页,searchResults 即为当前页数据)
|
||||||
watch(searchResults, () => {
|
const paginatedData = computed(() => searchResults.value)
|
||||||
currentPage.value = 1
|
|
||||||
})
|
|
||||||
|
|
||||||
// 分页后的数据
|
// 获取供应商列表(服务端分页)
|
||||||
const paginatedData = computed(() => {
|
const fetchData = async (page) => {
|
||||||
const start = (currentPage.value - 1) * pageSize.value
|
|
||||||
const end = start + pageSize.value
|
|
||||||
return searchResults.value.slice(start, end)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取供应商列表
|
|
||||||
const fetchData = async () => {
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const res = await getSupplierList()
|
const params = {
|
||||||
|
page: page || currentPage.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
}
|
||||||
|
const res = await getSupplierList(params)
|
||||||
if (res.code === 0 || res.code === 200) {
|
if (res.code === 0 || res.code === 200) {
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -83,6 +85,8 @@ const handleSearch = async () => {
|
|||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const params = {
|
const params = {
|
||||||
|
page: currentPage.value,
|
||||||
|
pageSize: pageSize.value,
|
||||||
type: filterType.value || undefined,
|
type: filterType.value || undefined,
|
||||||
status: filterStatus.value !== '' ? filterStatus.value : undefined
|
status: filterStatus.value !== '' ? filterStatus.value : undefined
|
||||||
}
|
}
|
||||||
@@ -96,7 +100,13 @@ const handleSearch = async () => {
|
|||||||
}
|
}
|
||||||
const res = await getSupplierList(params)
|
const res = await getSupplierList(params)
|
||||||
if (res.code === 0 || res.code === 200) {
|
if (res.code === 0 || res.code === 200) {
|
||||||
searchResults.value = res.data.list || res.data
|
if (res.data && Array.isArray(res.data.list)) {
|
||||||
|
searchResults.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else if (Array.isArray(res.data)) {
|
||||||
|
searchResults.value = res.data
|
||||||
|
total.value = res.data.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSearchResults.value = true
|
showSearchResults.value = true
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -217,9 +227,10 @@ const closeDetail = () => {
|
|||||||
currentDetail.value = null
|
currentDetail.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页码变化
|
// 页码变化(服务端分页:重新请求后端)
|
||||||
const handleCurrentChange = (val) => {
|
const handleCurrentChange = (val) => {
|
||||||
currentPage.value = val
|
currentPage.value = val
|
||||||
|
fetchData(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查权限
|
// 检查权限
|
||||||
@@ -239,8 +250,8 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
class="supplier-search-with-select" @keyup.enter="handleSearch">
|
class="supplier-search-with-select" @keyup.enter="handleSearch">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
||||||
<el-option label="ID" value="1" />
|
<el-option label="供应商编号" value="1" />
|
||||||
<el-option label="名称" value="2" />
|
<el-option label="供应商名称" value="2" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
@@ -277,12 +288,12 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<span class="total-count">共找到 {{ searchResults.length }} 条记录</span>
|
<span class="total-count">共找到 {{ total }} 条记录</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%"
|
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%"
|
||||||
@row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
@row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
||||||
<el-table-column prop="id" label="ID" width="70" />
|
<el-table-column prop="id" label="供应商编号" width="100" />
|
||||||
<el-table-column prop="name" label="供应商名称" min-width="150" />
|
<el-table-column prop="name" label="供应商名称" min-width="150" />
|
||||||
<el-table-column prop="contact" label="联系人" width="100" />
|
<el-table-column prop="contact" label="联系人" width="100" />
|
||||||
<el-table-column prop="phone" label="联系电话" width="130" />
|
<el-table-column prop="phone" label="联系电话" width="130" />
|
||||||
@@ -312,7 +323,7 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:total="searchResults.length"
|
:total="total"
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
prev-text="上一页"
|
prev-text="上一页"
|
||||||
next-text="下一页"
|
next-text="下一页"
|
||||||
@@ -335,7 +346,7 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="联系电话">
|
<el-form-item label="联系电话">
|
||||||
<el-input v-model="form.phone" placeholder="请输入联系电话" />
|
<el-input v-model="form.phone" placeholder="请输入联系电话" type="tel" maxlength="11" oninput="this.value=this.value.replace(/\D/g,'')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="地址">
|
<el-form-item label="地址">
|
||||||
@@ -370,7 +381,7 @@ const canOperate = computed(() => canUpdate.value || canDelete.value)
|
|||||||
<el-dialog v-model="showDetailDialog" title="供应商详情" width="650px" @close="closeDetail">
|
<el-dialog v-model="showDetailDialog" title="供应商详情" width="650px" @close="closeDetail">
|
||||||
<div v-if="currentDetail" class="detail-content">
|
<div v-if="currentDetail" class="detail-content">
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="供应商ID">{{ currentDetail.id }}</el-descriptions-item>
|
<el-descriptions-item label="供应商编号">{{ currentDetail.id }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="供应商名称">{{ currentDetail.name }}</el-descriptions-item>
|
<el-descriptions-item label="供应商名称">{{ currentDetail.name }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="联系人">{{ currentDetail.contact || '无' }}</el-descriptions-item>
|
<el-descriptions-item label="联系人">{{ currentDetail.contact || '无' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="联系电话">{{ currentDetail.phone || '无' }}</el-descriptions-item>
|
<el-descriptions-item label="联系电话">{{ currentDetail.phone || '无' }}</el-descriptions-item>
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ const canManage = computed(() => hasPermission('user', 'manage'))
|
|||||||
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
<el-select v-model="select" placeholder="请选择" style="width: 115px">
|
||||||
<el-option label="用户名" value="1" />
|
<el-option label="用户名" value="1" />
|
||||||
<el-option label="真实姓名" value="2" />
|
<el-option label="真实姓名" value="2" />
|
||||||
<el-option label="ID" value="3" />
|
<el-option label="用户编号" value="3" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
@@ -323,7 +323,7 @@ const canManage = computed(() => hasPermission('user', 'manage'))
|
|||||||
|
|
||||||
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%"
|
<el-table :data="paginatedData" v-loading="loading" border style="width: 100%"
|
||||||
@row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
@row-dblclick="handleRowDblClick" row-class-name="clickable-row">
|
||||||
<el-table-column prop="id" label="ID" width="80" />
|
<el-table-column prop="id" label="用户编号" width="90" />
|
||||||
<el-table-column prop="username" label="用户名" width="120" />
|
<el-table-column prop="username" label="用户名" width="120" />
|
||||||
<el-table-column prop="real_name" label="真实姓名" min-width="120">
|
<el-table-column prop="real_name" label="真实姓名" min-width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -414,7 +414,7 @@ const canManage = computed(() => hasPermission('user', 'manage'))
|
|||||||
<el-dialog v-model="showDetailDialog" title="用户详情" width="550px" @close="closeDetail">
|
<el-dialog v-model="showDetailDialog" title="用户详情" width="550px" @close="closeDetail">
|
||||||
<div v-if="currentDetail" class="detail-content">
|
<div v-if="currentDetail" class="detail-content">
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="用户ID">{{ currentDetail.id }}</el-descriptions-item>
|
<el-descriptions-item label="用户编号">{{ currentDetail.id }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="用户名">{{ currentDetail.username }}</el-descriptions-item>
|
<el-descriptions-item label="用户名">{{ currentDetail.username }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="真实姓名">{{ currentDetail.real_name || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="真实姓名">{{ currentDetail.real_name || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="部门">{{ currentDetail.dept_desc || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="部门">{{ currentDetail.dept_desc || '-' }}</el-descriptions-item>
|
||||||
|
|||||||
Reference in New Issue
Block a user