Commit 7952694f by 李宁

1

1 parent a02cf37a
......@@ -14,8 +14,11 @@ const handleLogin = (username: string, role: 'admin' | 'viewer') => {
}
if(isLoggedIn){
let name = JSON.parse(localStorage.getItem('pcUserInfo')).nickname||''
handleLogin( name, 'admin')
const userInfo = JSON.parse(localStorage.getItem('pcUserInfo') || '{}')
const name = userInfo?.nickname || ''
if(name) {
handleLogin(name, 'admin')
}
}
// 登出处理
......
import request from '../../request'
/**
* 全部商机-列表查询
* 业务酬金列表查询
*/
export function queryAllBusi(data) {
export function queryAllRewardList(data) {
return request({
url: '/compass/api/opportunity/page',
url: '/crm/getJobsList',
data,
})
}
/**
* 全部商机-商机审核
* 业务酬金批量上传:表格读取
*/
export function audioBusi(data) {
export function uploadReward(formData) {
return request({
url: '/compass/api/opportunity/audit',
data,
})
}
/**
* 全部商机-商机详情
*/
export function queryBusiDetail(data) {
return request({
url: '/compass/api/opportunity/detail',
data,
})
}
/**
* 全部商机-商机跟进记录查询
*/
export function queryBusiFollowList(data) {
return request({
url: '/compass/api/opportunity/follow/page',
data,
})
}
/**
* 全部商机-关闭商机
*/
export function closeBusi(data) {
return request({
url: '/compass/api/opportunity/close',
data,
})
}
/**
* 全部商机-标记成单
*/
export function dealBusi(data) {
return request({
url: '/compass/api/opportunity/deal',
data,
})
}
/**
* 全部商机-分配商机
*/
export function reassignBusi(data) {
return request({
url: '/compass/api/opportunity/reassign',
data,
})
}
/**
* 全部商机-记录管理员备注
*/
export function updateRemark(data) {
return request({
url: '/compass/api/opportunity/admin-remark',
data,
})
}
/**
* 全部商机-数据统计
*/
export function queryAllBusiStatistics(data) {
return request({
url: '/compass/api/opportunity/statistics',
data,
url: '/crm/readExcelJobs',
data: formData
})
}
/**
* 全部商机-查询所有商机标签列表
* 业务酬金提交
*/
export function queryBusiLabelList(data) {
export function uploadRewardSave(data) {
return request({
url: '/compass/api/opportunity/tag/page',
url: '/crm/batchUploadJobs',
data,
})
}
/**
* 商机标签的开始和关闭
*/
export function updateBusiLabelStatus(data) {
return request({
url: '/compass/api/opportunity/tag/status',
data,
})
}
/**
* 商机标签的删除
* 业务酬金修改
*/
export function deleteBusiLabel(data) {
export function updateReward(data) {
return request({
url: '/compass/api/opportunity/tag/delete',
url: '/crm/updateJob',
data,
})
}
/**
* 商机标签的创建和更新
*/
export function createAndUpdateTag(data) {
return request({
url: '/compass/api/opportunity/tag' + (data.id?'/update':''),
data,
})
}
/**
* 商机关闭原因列表查询
*/
export function queryBusiCloseReansonList(data) {
return request({
url: '/compass/api/opportunity/close-reason/page',
data,
})
}
/**
* 商机关闭原因:根据区域列表查询
*/
export function queryAreaCloseReansonList(data) {
return request({
url: '/compass/api/common/close-reason/page',
data,
})
}
/**
* 商机关闭原因添加和更新
*/
export function busiCloseReasonUpdate(data) {
return request({
url: '/compass/api/opportunity/close-reason'+(data.id?'/update':''),
data,
})
}
/**
* 商机关闭原因删除
*/
export function busiCloseReasonDel(data) {
return request({
url: '/compass/api/opportunity/close-reason/delete',
data,
})
}
/**
* 全部商机-新增商机
* 业务酬金删除
*/
export function createBusi(data) {
export function delReward(data) {
return request({
url: '/compass/api/opportunity/create',
url: '/crm/updateJob',
data,
})
}
\ No newline at end of file
......@@ -33,7 +33,7 @@
<input
ref="fileInputRef"
type="file"
accept=".csv"
accept=".csv,.xlsx"
@change="handleFileChange"
style="display: none"
/>
......@@ -269,11 +269,11 @@
</template>
<script setup lang="ts">
import { ref, computed, nextTick } from 'vue'
import { ref, computed, nextTick ,onMounted,getCurrentInstance} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Download, Upload, Plus, Search, CheckCircle, AlertCircle } from 'lucide-vue-next'
// import * as XLSX from 'xlsx' // 暂时注释掉,因为没有安装xlsx包
const { $api,$utils } = getCurrentInstance()!.appContext.config.globalProperties
// 业务规则类型定义
interface BusinessRule {
id: string
......@@ -300,6 +300,23 @@ const props = withDefaults(defineProps<Props>(), {
rules: () => []
})
onMounted(() => {
queryRewardList()
})
const queryRewardList = async ()=>{
try {
const response = await $api.queryAllRewardList({})
if (response.c === 0 && response.d) {
} else {
}
} catch (error) {
}
}
// Emits
const emit = defineEmits<{
add: [rule: Omit<BusinessRule, 'id' | 'createTime'>]
......@@ -429,8 +446,8 @@ const handleDownloadTemplate = () => {
// 创建下载链接
const link = document.createElement('a')
// 使用相对路径,确保本地和线上都能正常访问
link.href = '/static/file/rule_tem.xlsx'
link.download = '业务规则批量上传模板.xlsx'
link.href = './static/file/rule_tem.xlsx'
link.download = '业务酬金批量上传模板.xlsx'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
......@@ -463,64 +480,18 @@ const handleFileChange = async (e: Event) => {
// 验证文件格式
const fileName = file.name.toLowerCase()
if (!fileName.endsWith('.csv')) {
ElMessage.error('目前仅支持 .csv 格式的文件')
if (!fileName.endsWith('.csv') && !fileName.endsWith('.xlsx')) {
ElMessage.error('目前仅支持 csv和xlsx 格式的文件')
return
}
try {
let data: any[] = []
if (fileName.endsWith('.csv')) {
// 解析 CSV 文件
const text = await file.text()
const lines = text.split('\n').filter(line => line.trim())
if (lines.length < 2) {
ElMessage.error('文件内容为空')
return
}
// 跳过表头,从第二行开始解析
for (let i = 1; i < lines.length; i++) {
const line = (lines[i] || '').trim()
if (!line) continue
const columns = line.split(',').map(col => col.trim())
if (columns.length >= 3) {
data.push({
businessName: columns[0],
businessCode: columns[1],
estimatedReward: columns[2]
})
}
}
} else {
// 解析 XLSX 文件 (暂时禁用)
ElMessage.error('XLSX功能暂未启用,请使用CSV格式')
return
// const arrayBuffer = await file.arrayBuffer()
// const workbook = XLSX.read(arrayBuffer, { type: 'array' })
// const sheetName = workbook.SheetNames[0]
// const worksheet = workbook.Sheets[sheetName]
// const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 })
const formData = new FormData()
formData.append('file', file)
// 跳过表头(XLSX 逻辑禁用中)
}
// 验证数据量
if (data.length === 0) {
ElMessage.error('文件中没有有效数据')
return
}
if (data.length > 1000) {
ElMessage.error('数据量超过1000条限制,请分批上传')
return
}
const response = await $api.uploadReward(formData)
// 验证并导入数据
processUploadData(data)
console.log(response)
} catch (error) {
console.error('文件解析失败:', error)
ElMessage.error('文件解析失败,请检查文件格式是否正确')
......
......@@ -297,12 +297,12 @@ const platformLogo = ref(platformLogoImg)
const { $api } = getCurrentInstance()!.appContext.config.globalProperties
// 本地Role类型定义,确保permissions字段是必需的
interface Role {
id: string
name: string
description?: string
level: '地市级' | '区县级' | '一线人员'
permissions: string[]
status: '启用' | '禁用'
id: number
roleName: string
status: 1 | 0
remark?: string
permissionIds?: string[]
permissions?: string[]
createTime?: string
}
interface DesktopMainProps {
......@@ -315,7 +315,7 @@ const isSidebarCollapsed = ref(false)
const activeMenu = ref<string>('orders') // 当前激活的菜单
const activeView = ref<string>('orders') // 当前显示的视图
const selectedOrderId = ref<string | null>(null) // 当前查看的订单ID
const userInfo = ref(localStorage.getItem('pcUserInfo')?JSON.parse(localStorage.getItem('pcUserInfo')):{})
const userInfo = ref(localStorage.getItem('pcUserInfo') ? JSON.parse(localStorage.getItem('pcUserInfo') as string) : {})
// 菜单配置
// const businessMenuItems = [
// { id: 'orders', label: '登记订单管理', icon: LayoutDashboard },
......@@ -323,11 +323,11 @@ const userInfo = ref(localStorage.getItem('pcUserInfo')?JSON.parse(localStorage.
// ]
const businessMenuItems = computed(() => {
let va = userInfo.value
if(va.functions){
let arr = va.functions.filter(item=>{return item.id==1})
if(va?.functions){
let arr = va.functions.filter((item: any) => {return item.id==1})
if(arr.length>0 && arr[0].children){
let barr = []
arr[0].children.forEach(item=>{
let barr: any[] = []
arr[0].children.forEach((item: any) => {
if(item.id == 2){
barr.push({ id: 'orders', label: '登记订单管理', icon: LayoutDashboard })
}
......@@ -335,7 +335,7 @@ const businessMenuItems = computed(() => {
barr.push({ id: 'business', label: '业务酬金管理', icon: DollarSign })
}
})
return barr
}
}
......@@ -347,11 +347,11 @@ const businessMenuItems = computed(() => {
// ]
const systemMenuItems = computed(() => {
let va = userInfo.value
if(va.functions){
let arr = va.functions.filter(item=>{return item.id==14})
if(va?.functions){
let arr = va.functions.filter((item: any) => {return item.id==14})
if(arr.length>0 && arr[0].children){
let barr = []
arr[0].children.forEach(item=>{
let barr: any[] = []
arr[0].children.forEach((item: any) => {
if(item.id == 15){
barr.push({ id: 'roles', label: '角色管理', icon: RoleIcon })
}
......@@ -359,7 +359,7 @@ const systemMenuItems = computed(() => {
barr.push({ id: 'users', label: '账号管理', icon: Users })
}
})
return barr
}
}
......@@ -429,14 +429,15 @@ interface BusinessRule {
interface Organization {
id: string
name: string
areaCode: string
type: "地市" | "区县" | "客户经理团队"
parentId?: string
children?: Organization[]
}
// 角色管理数据
const roles = ref<Role[]>()
const roles = ref<Role[]>([])
// 权限数据
const permissions = ref<Permission[]>(userInfo.value.functions || [])
const permissions = ref<Permission[]>(userInfo.value?.functions || [])
// 根据订单ID获取订单详情
const getOrderById = (orderId: string) => {
return allOrders.value.find((order: any) => order.id === orderId)
......@@ -472,9 +473,11 @@ const handleBackToOrders = () => {
}
const handleUpdateOrder = (updates: any) => {
// 更新 allOrders 中的订单数据
const orderIndex = allOrders.value.findIndex(order => order.id === selectedOrderId.value)
if (orderIndex !== -1) {
allOrders.value[orderIndex] = { ...allOrders.value[orderIndex], ...updates }
if (selectedOrderId.value) {
const orderIndex = allOrders.value.findIndex(order => order.id === selectedOrderId.value)
if (orderIndex !== -1) {
allOrders.value[orderIndex] = { ...allOrders.value[orderIndex], ...updates }
}
}
console.log('更新订单:', updates)
ElMessage.success('订单更新成功')
......@@ -549,9 +552,12 @@ const handleDeleteBusinessRule = (ruleId: string) => {
// 角色管理方法
const handleAddRole = (roleData: any) => {
const newRole: Role = {
id: `role-${Date.now()}`,
...roleData,
id: Date.now(),
name: roleData.name || roleData.roleName,
level: roleData.level,
description: roleData.description,
permissions: roleData.permissions || roleData.permissionIds || [],
status: 1,
createTime: new Date().toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
......@@ -564,7 +570,7 @@ const handleAddRole = (roleData: any) => {
roles.value.push(newRole)
console.log('新增角色:', newRole)
}
const handleUpdateRole = (roleId: string, updates: any) => {
const handleUpdateRole = (roleId: number, updates: any) => {
const roleIndex = roles.value.findIndex(role => role.id === roleId)
if (roleIndex !== -1) {
const existingRole = roles.value[roleIndex]
......@@ -579,7 +585,7 @@ const handleUpdateRole = (roleId: string, updates: any) => {
}
}
// 组织架构数据
const organizations = ref<Organization[]>()
const organizations = ref<Organization[]>([])
// 生命周期
onMounted(() => {
......@@ -598,7 +604,7 @@ const getArea = async ()=>{
pa.name = pa.areaName
pa.parentId += ''
pa.children.forEach(item=>{
pa.children.forEach((item: any) => {
item.id += ''
item.type = item.areaLevel==2?'地市':'区县'
item.name = item.areaName
......@@ -626,7 +632,7 @@ const users = ref<UserType[]>([
roleId: 'role-001',
phone: '13800138000',
email: 'admin@cmcc.com',
status: '正常',
status: '1' as '0' | '1',
createTime: '2025-10-20 08:00:00',
creatorId: 'system'
},
......@@ -638,7 +644,7 @@ const users = ref<UserType[]>([
roleId: 'role-002',
phone: '13800138001',
email: 'zhangsan@cmcc.com',
status: '正常',
status: '1' as '0' | '1',
createTime: '2025-10-20 09:00:00',
creatorId: 'user-001'
},
......@@ -650,7 +656,7 @@ const users = ref<UserType[]>([
roleId: 'role-002',
phone: '13800138002',
email: 'lisi@cmcc.com',
status: '禁用',
status: '0' as '0' | '1',
createTime: '2025-10-20 10:00:00',
creatorId: 'user-001'
},
......@@ -662,7 +668,7 @@ const users = ref<UserType[]>([
roleId: 'role-003',
phone: '13800138003',
email: 'wangwu@cmcc.com',
status: '正常',
status: '1' as '0' | '1',
createTime: '2025-10-20 11:00:00',
creatorId: 'user-001'
}
......
......@@ -196,7 +196,7 @@ const handleFilter = async () => {
} else {
ElMessage.error(response.msg || '查询失败');
}
} catch (error) {
} catch (error: any) {
ElMessage.error('查询失败: ' + error.message);
}
}
......@@ -213,7 +213,8 @@ export interface Permission {
export interface Role {
id: Number
roleName: string
name: string
level: '地市级' | '区县级' | '一线人员'
status: RoleStatus
remark?: string
permissionIds?: string[]
......@@ -261,7 +262,7 @@ const topLevelPermissions = computed(() =>
const filteredRoles = ref([])
const getAllIds = (tree)=>{
const getAllIds = (tree: any[]) => {
const ids = [] // 结果池
const stack = [...tree] // 根节点入栈
......
......@@ -383,8 +383,8 @@ const formData = ref({
isActive: true
})
// 计算属性
const availableRoles = ref([])
const filteredUsers = ref([])
const availableRoles = ref<any[]>([])
const filteredUsers = ref<any[]>([])
const topLevelOrganizations = computed(() =>
props.organizations.filter(o => o.id)
)
......@@ -396,7 +396,7 @@ const getRoleList = async ()=>{
try {
const response = await $api.queryRoleList({})
if (response && response.c === 0) {
availableRoles.value = response.d.filter(item=>{return item.status==1})
availableRoles.value = response.d.filter((item: any) => {return item.status==1})
}
} catch (error) {
......@@ -482,21 +482,21 @@ const handleOpenAddDialog = () => {
username: '',
realName: '',
phone: '',
accountType: '',
accountType: '' as '1' | '2' | '3',
organizationId: '',
roleId: '',
isActive: true
}
isDialogOpen.value = true
}
const handleOpenEditDialog = (row) => {
const handleOpenEditDialog = (row: any) => {
editingUser.value = row
console.log('编辑用户数据:', row)
formData.value = {
username: row.userCode,
realName: row.username,
phone: row.phone || '',
accountType: row.userType+'',
accountType: (row.userType + '') as '1' | '2' | '3',
organizationId: row.areaId + '',
roleId: row.roleId,
isActive: row.status === 1
......@@ -628,7 +628,7 @@ const handleSave = async () => {
return
}
let data = {
let data: any = {
id: editingUser.value?editingUser.value.id:'',
userCode: formData.value.username.trim(),
username: formData.value.realName.trim(),
......@@ -640,7 +640,6 @@ const handleSave = async () => {
}
if(editingUser.value){
delete data.userCode
if(editingUser.value.username == formData.value.realName.trim()){
delete data.username
}
......
......@@ -15,13 +15,13 @@
<script setup lang="ts">
import { ref } from 'vue'
import RoleManagement, { type Role, type Permission } from '@/components/RoleManagement.vue'
import RoleManagement, { type Role, type Permission, type RoleStatus } from '@/components/RoleManagement.vue'
import { ElMessage } from 'element-plus'
// 测试数据
const roles = ref<Role[]>([
{
id: 'role-001',
id: 1 as Number,
name: '区县全权管理员',
description: '拥有区县级别的所有管理权限,可以管理订单、用户和业务规则',
level: '区县级',
......@@ -45,25 +45,25 @@ const roles = ref<Role[]>([
'system:account:create',
'system:account:edit'
],
status: '启用',
status: 1 as RoleStatus,
createTime: '2025-10-20 09:00:00'
},
{
id: 'role-002',
id: 2 as Number,
name: '订单管理员',
description: '负责订单的日常管理和处理',
level: '一线人员',
permissions: ['order', 'order:view', 'order:complete', 'order:reward', 'order:approve'],
status: '启用',
status: 1 as RoleStatus,
createTime: '2025-10-20 09:30:00'
},
{
id: 'role-003',
id: 3 as Number,
name: '业务规则管理员',
description: '负责业务规则的配置和维护',
level: '区县级',
permissions: ['business', 'business:view', 'business:create', 'business:edit'],
status: '启用',
status: 1 as RoleStatus,
createTime: '2025-10-20 10:00:00'
}
])
......@@ -205,11 +205,14 @@ const permissions = ref<Permission[]>([
])
// 事件处理
const handleAddRole = (roleData: Omit<Role, 'id' | 'createTime'>) => {
const newRole: Role = {
id: `role-${Date.now()}`,
...roleData,
permissions: roleData.permissionIds || roleData.permissions || [],
const handleAddRole = (roleData: any) => {
const newRole: any = {
id: Date.now(),
name: roleData.name,
description: roleData.description,
level: roleData.level,
permissions: roleData.permissions || [],
status: 1,
createTime: new Date().toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
......@@ -224,7 +227,7 @@ const handleAddRole = (roleData: Omit<Role, 'id' | 'createTime'>) => {
console.log('新增角色:', newRole)
}
const handleUpdateRole = (roleId: string, updates: Partial<Role>) => {
const handleUpdateRole = (roleId: number, updates: Partial<Role>) => {
const roleIndex = roles.value.findIndex(role => role.id === roleId)
if (roleIndex !== -1) {
roles.value[roleIndex] = { ...roles.value[roleIndex], ...updates } as Role
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!