diff --git a/package.json b/package.json index fe3c2b5..621d8de 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,9 @@ { "dependencies": { + "html2canvas": "^1.4.1", + "mammoth": "^1.9.0", + "pdf-lib": "^1.17.1", + "pdfjs-dist": "^5.1.91", "qrcode.vue": "^3.6.0" } } diff --git a/pc/.env.development b/pc/.env.development index 6a0355f..445b3c2 100644 --- a/pc/.env.development +++ b/pc/.env.development @@ -1,4 +1,4 @@ NODE_ENV = 'development' # 开发环境API地址 -VUE_APP_BASE_API = http://192.168.137.3:8080/api \ No newline at end of file +VUE_APP_BASE_API = http://192.168.137.38:8080 \ No newline at end of file diff --git a/pc/src/api/finance.js b/pc/src/api/finance.js index 3c9eccf..3a17024 100644 --- a/pc/src/api/finance.js +++ b/pc/src/api/finance.js @@ -90,4 +90,171 @@ export function deleteFeeType(id) { url: `/finance/type/${id}`, method: 'delete' }) +} + + +// 收据编号规则相关接口 +export function listReceiptRule(params) { + return request({ + url: '/receipt/number-rule/page', + method: 'get', + params + }) +} + +export function addReceiptRule(data) { + return request({ + url: '/receipt/number-rule', + method: 'post', + data + }) +} + +export function deleteReceiptRule(id) { + return request({ + url: `/receipt/number-rule/${id}`, + method: 'delete' + }) +} + +export function getNextReceiptNumber(ruleId) { + return request({ + url: `/receipt/number/next/${ruleId}`, + method: 'get' + }) +} + +export function getBatchReceiptNumbers(ruleId, count) { + return request({ + url: `/receipt/numbers/${ruleId}/${count}`, + method: 'get' + }) +} + +// 收据模板相关接口 +export function getReceiptTemplateList(params) { + return request({ + url: '/receipt/template/page', + method: 'get', + params + }) +} + +export function addReceiptTemplate(data) { + return request({ + url: '/receipt/template', + method: 'post', + data + }) +} + +export function updateReceiptTemplate(id, data) { + return request({ + url: `/receipt/template/${id}`, + method: 'put', + data + }) +} + +export function deleteReceiptTemplate(id) { + return request({ + url: `/receipt/template/${id}`, + method: 'delete' + }) +} + +export function previewReceiptTemplate(id) { + return request({ + url: `/receipt/template/preview/${id}`, + method: 'get', + responseType: 'blob' + }) +} + +export function downloadReceiptTemplate(id) { + return request({ + url: `/receipt/template/download/${id}`, + method: 'get', + responseType: 'blob' + }) +} + +export function downloadExampleTemplate() { + return request({ + url: '/receipt/template/download-example', + method: 'get', + responseType: 'blob' + }) +} + +export function getReceiptKeywords() { + return request({ + url: '/receipt/template/keywords', + method: 'get' + }) +} + +export function checkTemplateName(params) { + return request({ + url: '/receipt/template/check-name', + method: 'get', + params + }) +} + +// 收款方信息相关接口 +export function getPayeeInfo(params) { + if (typeof params === 'object') { + // 查询列表 + return request({ + url: '/receipt/payee/page', + method: 'get', + params + }) + } else { + // 查询详情 + return request({ + url: `/receipt/payee/${params}`, + method: 'get' + }) + } +} + +export function addPayeeInfo(data) { + return request({ + url: '/receipt/payee', + method: 'post', + data + }) +} + +export function updatePayeeInfo(id, data) { + return request({ + url: `/receipt/payee/${id}`, + method: 'put', + data + }) +} + +export function deletePayeeInfo(id) { + return request({ + url: `/receipt/payee/${id}`, + method: 'delete' + }) +} + +// 项目列表 +export function getProjectList() { + return request({ + url: '/project/list', + method: 'get' + }) +} + +// 获取楼宇列表 +export function getBuildingList(projectId) { + return request({ + url: `/business/building/list/${projectId}`, + method: 'get' + }) } \ No newline at end of file diff --git a/pc/src/api/merchant.js b/pc/src/api/merchant.js new file mode 100644 index 0000000..b42ca97 --- /dev/null +++ b/pc/src/api/merchant.js @@ -0,0 +1,255 @@ +import request from '@/utils/request' + +// 招商团队相关API +export function getMerchantTeamList(params) { + return request({ + url: '/business/team/list', + method: 'get', + params + }) +} + +export function addMerchantTeam(data) { + return request({ + url: '/business/team', + method: 'post', + data + }) +} + +export function updateMerchantTeam(data) { + return request({ + url: '/business/team', + method: 'put', + data + }) +} + +export function deleteMerchantTeam(id) { + return request({ + url: `/business/team/${id}`, + method: 'delete' + }) +} + +// 招商人员相关API +export function getMerchantPersonnelList(params) { + return request({ + url: '/business/personnel/list', + method: 'get', + params + }) +} + +export function getPersonnelByTeamId(teamId) { + return request({ + url: `/business/personnel/team/${teamId}`, + method: 'get' + }) +} + +export function getPersonnelDetail(id) { + return request({ + url: `/business/personnel/${id}`, + method: 'get' + }) +} + +export function addMerchantPersonnel(data) { + return request({ + url: '/business/personnel', + method: 'post', + data + }) +} + +export function removeMerchantPersonnel(id) { + return request({ + url: `/business/personnel/${id}`, + method: 'delete' + }) +} + +// 成员管理相关API +export function getDepartmentTree() { + return request({ + url: '/business/member/dept/tree', + method: 'get' + }) +} + +export function getDepartmentMemberTree() { + return request({ + url: '/business/member/tree', + method: 'get' + }) +} + +export function getManagerList() { + return request({ + url: '/business/member/managers', + method: 'get' + }) +} + +export function getMemberList(params) { + return request({ + url: '/business/member/list', + method: 'get', + params + }) +} + +export function getMembersByDeptId(deptId) { + return request({ + url: `/business/member/dept/${deptId}`, + method: 'get' + }) +} + +export function getMemberDetail(memberId) { + return request({ + url: `/business/member/${memberId}`, + method: 'get' + }) +} + +// 获取项目列表 +export function getProjectList() { + return request({ + url: '/project/list', + method: 'get' + }) +} + +// 获取线索数量 +export function getClueCount(personnelId) { + return request({ + url: `/merchant/clue/count/${personnelId}`, + method: 'get' + }) +} + +// 获取意向客户数量 +export function getIntentCustomerCount(personnelId) { + return request({ + url: `/merchant/intent-customer/count/${personnelId}`, + method: 'get' + }) +} + +// 获取合同数量 +export function getContractCount(personnelId) { + return request({ + url: `/merchant/contract/count/${personnelId}`, + method: 'get' + }) +} + +// 标签分组相关API +export function getTagGroupList(params) { + return request({ + url: '/business/tag-group/list', + method: 'get', + params + }) +} + +export function getAllTagGroups() { + return request({ + url: '/business/tag-group/all', + method: 'get' + }) +} + +export function getTagGroupDetail(id) { + return request({ + url: `/business/tag-group/${id}`, + method: 'get' + }) +} + +export function addTagGroup(data) { + return request({ + url: '/business/tag-group', + method: 'post', + data + }) +} + +export function updateTagGroup(data) { + return request({ + url: '/business/tag-group', + method: 'put', + data + }) +} + +export function deleteTagGroup(id) { + return request({ + url: `/business/tag-group/${id}`, + method: 'delete' + }) +} + +export function checkTagGroupName(params) { + return request({ + url: '/business/tag-group/check-name', + method: 'get', + params + }) +} + +// 标签相关API +export function getTagList(params) { + return request({ + url: '/business/tag/list', + method: 'get', + params + }) +} + +export function getTagListByGroupId(groupId) { + return request({ + url: `/business/tag/group/${groupId}`, + method: 'get' + }) +} + +export function getTagDetail(id) { + return request({ + url: `/business/tag/${id}`, + method: 'get' + }) +} + +export function addTag(data) { + return request({ + url: '/business/tag', + method: 'post', + data + }) +} + +export function updateTag(data) { + return request({ + url: '/business/tag', + method: 'put', + data + }) +} + +export function deleteTag(id) { + return request({ + url: `/business/tag/${id}`, + method: 'delete' + }) +} + +export function checkTagName(params) { + return request({ + url: '/business/tag/check-name', + method: 'get', + params + }) +} \ No newline at end of file diff --git a/pc/src/components/MemberSelector/index.vue b/pc/src/components/MemberSelector/index.vue new file mode 100644 index 0000000..b3cdfbf --- /dev/null +++ b/pc/src/components/MemberSelector/index.vue @@ -0,0 +1,655 @@ + + + + + + + + + + + + + + + + 全选 + + + + + + {{ department.name }} + + + + + + + + {{ member.name }} + + + + + handleMemberCheckChange(val, member, department)" + >{{ member.name }} + + + + + + + + + {{ subDept.name }} + + + + + + + {{ member.name }} + + + + + handleMemberCheckChange(val, member, subDept)" + >{{ member.name }} + + + + + + + + + + + + + + 已选择:清空 + + + + + {{ tempSelectedMember.name.slice(-1) }} + {{ tempSelectedMember.name }} + + + 未选择 + + + + + {{ member.name.slice(-1) }} + {{ member.name }} + + + + 未选择 + + + + + + + + + + + + \ No newline at end of file diff --git a/pc/src/router/index.js b/pc/src/router/index.js index c653802..58d4b6c 100644 --- a/pc/src/router/index.js +++ b/pc/src/router/index.js @@ -4,6 +4,7 @@ import Layout from '@/layout/index' import systemRoutes from './modules/system' import projectRoutes from './modules/project' import financeRoutes from './modules/finance' +import merchantRoutes from './modules/merchant' Vue.use(VueRouter) @@ -30,6 +31,7 @@ const routes = [ systemRoutes, projectRoutes, financeRoutes, + merchantRoutes, { path: '/asset', component: Layout, diff --git a/pc/src/router/modules/finance.js b/pc/src/router/modules/finance.js index b78ee1d..e0769ee 100644 --- a/pc/src/router/modules/finance.js +++ b/pc/src/router/modules/finance.js @@ -12,6 +12,12 @@ export default { component: () => import('@/views/finance/feeType/index.vue'), name: 'FeeType', meta: { title: '费用类型', icon: 'el-icon-tickets' } + }, + { + path: 'receiptSetting', + component: () => import('@/views/finance/receiptSetting/index.vue'), + name: 'ReceiptSetting', + meta: { title: '收据设置', icon: 'el-icon-document' } } ] } \ No newline at end of file diff --git a/pc/src/router/modules/merchant.js b/pc/src/router/modules/merchant.js new file mode 100644 index 0000000..c049cae --- /dev/null +++ b/pc/src/router/modules/merchant.js @@ -0,0 +1,33 @@ +export default { + path: '/merchant', + component: () => import('@/layout/index'), + redirect: '/merchant/merchant-personnel', + name: 'Merchant', + meta: { title: '招商管理', icon: 'el-icon-user-solid' }, + children: [ + { + path: 'merchant-personnel', + component: () => import('@/views/merchant/merchant-personnel/index.vue'), + name: 'MerchantPersonnel', + meta: { title: '招商人员', icon: 'el-icon-user' } + }, + { + path: 'tag-management', + component: () => import('@/views/merchant/tag-management/index.vue'), + name: 'TagManagement', + meta: { title: '标签管理', icon: 'el-icon-collection-tag' } + }, + { + path: 'clue-management', + component: () => import('@/views/merchant/clue-management/index.vue'), + name: 'ClueManagement', + meta: { title: '线索管理', icon: 'el-icon-chat-line-square' } + }, + { + path: 'intent-customer', + component: () => import('@/views/merchant/intent-customer/index.vue'), + name: 'IntentCustomer', + meta: { title: '意向客户', icon: 'el-icon-s-custom' } + } + ] +} \ No newline at end of file diff --git a/pc/src/utils/constants.js b/pc/src/utils/constants.js new file mode 100644 index 0000000..1a20e8c --- /dev/null +++ b/pc/src/utils/constants.js @@ -0,0 +1,5 @@ +// API响应状态码 +export const API_SUCCESS_CODE = '0000000000000000' + + +// 其他常量可以在此添加 diff --git a/pc/src/utils/request.js b/pc/src/utils/request.js index bb89bc2..29134d3 100644 --- a/pc/src/utils/request.js +++ b/pc/src/utils/request.js @@ -1,9 +1,10 @@ import axios from 'axios' import { Message } from 'element-ui' +import { API_SUCCESS_CODE } from './constants' // 创建axios实例 const service = axios.create({ - // baseURL: '/api', // 修改为相对路径,使用代理 + // baseURL: '/', // 修改为相对路径,使用代理 baseURL: process.env.VUE_APP_BASE_API, // 使用环境变量中的接口地址 timeout: 10000 // 请求超时时间 @@ -30,8 +31,8 @@ service.interceptors.response.use( } const res = response.data - // 如果返回的状态码不是000000,则判断为错误 - if (res.code !== '000000') { + // 如果返回的状态码不是成功码,则判断为错误 + if (res.code !== API_SUCCESS_CODE) { Message({ message: res.msg || res.message || '系统错误', type: 'error', diff --git a/pc/src/views/finance/feeType/index.vue b/pc/src/views/finance/feeType/index.vue index c63e33a..083e8f7 100644 --- a/pc/src/views/finance/feeType/index.vue +++ b/pc/src/views/finance/feeType/index.vue @@ -162,6 +162,7 @@ import { updateFeeType, deleteFeeType } from '@/api/finance' +import { API_SUCCESS_CODE } from '@/utils/constants' export default { name: 'FeeTypeManagement', @@ -238,7 +239,7 @@ export default { // 获取分类列表 getCategoryList() { getAllFeeCategories().then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.categoryList = response.data if (this.categoryList.length > 0 && !this.selectedCategoryId) { this.handleCategorySelect(this.categoryList[0].id.toString()) @@ -253,7 +254,7 @@ export default { if (this.categoryQuery) { const params = { categoryName: this.categoryQuery, pageNum: 1, pageSize: 100 } getFeeCategories(params).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.categoryList = response.data.list } else { this.$message.error(response.message || '查询失败') @@ -275,7 +276,7 @@ export default { getTypeList() { this.loading = true getFeeTypes(this.queryParams).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.typeList = response.data.list this.total = response.data.total } else { @@ -329,7 +330,7 @@ export default { // 编辑分类操作 handleEditCategory(row) { getFeeCategory(row.id).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { const categoryData = response.data // 确保保证金类型字段是字符串 if (categoryData.feeTpNo !== undefined) { @@ -353,7 +354,7 @@ export default { if (valid) { if (this.categoryForm.id) { updateFeeCategory(this.categoryForm.id, this.categoryForm).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.$message.success('修改成功') this.categoryOpen = false this.getCategoryList() @@ -363,7 +364,7 @@ export default { }) } else { addFeeCategory(this.categoryForm).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.$message.success('新增成功') this.categoryOpen = false this.getCategoryList() @@ -383,7 +384,7 @@ export default { type: 'warning' }).then(() => { deleteFeeCategory(row.id).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.$message.success('删除成功') this.getCategoryList() // 如果删除的是当前选中的分类,重置选中状态 @@ -423,7 +424,7 @@ export default { // 修改费用类型按钮操作 handleEditType(row) { getFeeType(row.id).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { // 先设置数据 const typeData = response.data // 确保所有字段都是字符串类型 @@ -461,7 +462,7 @@ export default { if (this.typeForm.id) { updateFeeType(this.typeForm.id, submitData).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.$message.success('修改成功') this.typeOpen = false this.getTypeList() @@ -471,7 +472,7 @@ export default { }) } else { addFeeType(submitData).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.$message.success('新增成功') this.typeOpen = false this.getTypeList() @@ -491,7 +492,7 @@ export default { type: 'warning' }).then(() => { deleteFeeType(row.id).then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.$message.success('删除成功') this.getTypeList() } else { @@ -519,7 +520,7 @@ export default { // 加载完整的分类列表 loadFullCategoryList() { getAllFeeCategories().then(response => { - if (response.code === '000000') { + if (response.code === API_SUCCESS_CODE) { this.categoryList = response.data } }) diff --git a/pc/src/views/finance/receiptSetting/PayeeInfo.vue b/pc/src/views/finance/receiptSetting/PayeeInfo.vue new file mode 100644 index 0000000..41c2c02 --- /dev/null +++ b/pc/src/views/finance/receiptSetting/PayeeInfo.vue @@ -0,0 +1,582 @@ + + + + + + + + 搜索 + 重置 + 新增收款方信息 + + + + + + + {{ formatCompanyName(scope.row.companyId) }} + + + + + + + + + {{ formatBuildingNames(scope.row.buildingIds) }} + + + + + 编辑 + 删除 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ node.label }} + + + + + + + + + + + + + + + 确定要删除该收款方信息吗? + + + + + + + + + \ No newline at end of file diff --git a/pc/src/views/finance/receiptSetting/ReceiptTemplate.vue b/pc/src/views/finance/receiptSetting/ReceiptTemplate.vue new file mode 100644 index 0000000..1fa99d8 --- /dev/null +++ b/pc/src/views/finance/receiptSetting/ReceiptTemplate.vue @@ -0,0 +1,940 @@ + + + + + + + 搜索 + 重置 + + 新增收据模版 + 下载样例模板 + + + + + + + + + {{ formatBuildingNames(scope.row.buildingIds) }} + + + + + 预览 + 下载 + 编辑 + 删除 + + + + + + + + + + + + + + + + 收据信息 + + + {{ item }} + + + + + + 交收款方 + + + {{ item }} + + + + + + 房源信息 + + + {{ item }} + + + + + + 账单信息 + + + {{ item }} + + + + + + + + + + + + + + + 点击上传 + 仅支持docx格式,大小不超过5M + + + + + 更新模板文件 + + + + + + + + {{ node.label }} + + + + + + + + + + + + + + + + + 确定要删除该收据模板吗? + + + + + + + + + + + + + 预览加载失败,请尝试下载后查看 + + 下载文档 + + + + + + + + + + + \ No newline at end of file diff --git a/pc/src/views/finance/receiptSetting/index.vue b/pc/src/views/finance/receiptSetting/index.vue new file mode 100644 index 0000000..a194589 --- /dev/null +++ b/pc/src/views/finance/receiptSetting/index.vue @@ -0,0 +1,474 @@ + + + + + + + + 搜索 + 重置 + 新增收据编号规则 + + + + + + + + + + + + {{ formatProjectNames(scope.row.projectList) }} + + + + + 删除 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ node.label }} + + + + + + + + + + + + + + + 确定要删除该收据编号规则吗? + + + + + + + + + \ No newline at end of file diff --git a/pc/src/views/merchant/clue-management/index.vue b/pc/src/views/merchant/clue-management/index.vue new file mode 100644 index 0000000..ff17d85 --- /dev/null +++ b/pc/src/views/merchant/clue-management/index.vue @@ -0,0 +1,29 @@ + + + 线索管理页面 + 这里是线索管理的内容,根据需求继续完善 + + + + + + \ No newline at end of file diff --git a/pc/src/views/merchant/intent-customer/index.vue b/pc/src/views/merchant/intent-customer/index.vue new file mode 100644 index 0000000..53b525d --- /dev/null +++ b/pc/src/views/merchant/intent-customer/index.vue @@ -0,0 +1,29 @@ + + + 意向客户页面 + 这里是意向客户的内容,根据需求继续完善 + + + + + + \ No newline at end of file diff --git a/pc/src/views/merchant/merchant-personnel/index.vue b/pc/src/views/merchant/merchant-personnel/index.vue new file mode 100644 index 0000000..5935e24 --- /dev/null +++ b/pc/src/views/merchant/merchant-personnel/index.vue @@ -0,0 +1,1559 @@ + + + + + + + 1. 招商团队可按照区域或其他方式进行分类,主要用作招商人员分组管理; + 2. 可以批量添加部门或个人为招商人员;若批量添加部门,则该部门下所有成员都会被设为招商人员; + 3. 等权限设置好,会自动按照上级管理流程。 + + + + + + + + + + 搜索 + 重置 + 新增招商人员 + + + + + + + + + + + + + + 移除人员 + + + + + + + + + + + + + + + + + + + 搜索 + 重置 + 新增团队 + + + + + + + + + + + + 编辑 + 删除 + + + + + + + + + + + + + + + + + + + 选择 + + {{ teamForm.managerName }} {{ teamForm.managerPhone ? `(${teamForm.managerPhone})` : '' }} + + + + + + + + + + + + + + + + + + + + + 添加 + + + {{ member.name }} + + + + + + + + + + + + + + + + 按成员选择 + 按部门选择 + + + + + + + + + + 搜索结果 + + + {{item.memberName}} + {{item.deptName}} + + + + + + + + + + + 已选择: + 清空 + + + + {{ member.name }} + + + + + + + + + + + + + + 确定要删除该招商团队吗? + + + + + + + + + 确定要移除该招商人员吗? + + + + + + + + + \ No newline at end of file diff --git a/pc/src/views/merchant/tag-management/index.vue b/pc/src/views/merchant/tag-management/index.vue new file mode 100644 index 0000000..1c551ba --- /dev/null +++ b/pc/src/views/merchant/tag-management/index.vue @@ -0,0 +1,844 @@ + + + + + + + + 分组管理 + + 新增 + + + + + + + + + + + {{ group.groupName }} + + + + + + + + + + + + + + + + + + + + 标签管理 + - {{ activeGroup.groupName }} + + + 新增标签 + + + + + + + + + + + + 查询 + 重置 + + + + + + + + + + + + + + + + 编辑 + + + 删除 + + + + + + + + + + + + + + + + + + + + + + + + 按回车键可输入多个标签名称 + + + + + + + + + + + + + + + + + + 按回车键可输入多个标签名称 + + + + + + + + + + \ No newline at end of file diff --git a/pc/vue.config.js b/pc/vue.config.js index d2a95fb..74ffd64 100644 --- a/pc/vue.config.js +++ b/pc/vue.config.js @@ -10,14 +10,14 @@ module.exports = { warnings: false, errors: true }, - proxy: { - '/api': { - target: 'http://localhost:8080', - changeOrigin: true, - pathRewrite: { - '^/api': '/api' - } - } - } + // proxy: { + // '/': { + // target: 'http://192.168.137.3:8080/api', + // changeOrigin: true, + // pathRewrite: { + // '^/api': '/api' + // } + // } + // } } } \ No newline at end of file diff --git a/pc/web (2).zip b/pc/web (2).zip deleted file mode 100644 index 8f8f1f1..0000000 Binary files a/pc/web (2).zip and /dev/null differ diff --git a/pc/web.zip b/pc/web.zip deleted file mode 100644 index 107e0a6..0000000 Binary files a/pc/web.zip and /dev/null differ
预览加载失败,请尝试下载后查看
这里是线索管理的内容,根据需求继续完善
这里是意向客户的内容,根据需求继续完善