diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f71b978
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+node_modules/
+.DS_Store
+.idea/
+.vscode/
+.env
+.env.local
+
+
+package-lock.json
+yarn.lock
diff --git a/h5/README.md b/h5/README.md
new file mode 100644
index 0000000..06efde7
--- /dev/null
+++ b/h5/README.md
@@ -0,0 +1,102 @@
+# H5在线缴费系统
+
+基于Vue.js和Vant UI的移动端在线缴费系统,提供账单管理、缴费支付、对账等功能。
+
+## 主要功能
+
+- 缴费账单列表查询:查询当前业户待缴费的账单
+- 预缴账单列表查询:查询当前业户未到期的预缴账单
+- 缴费支付:支持个对公和公对公两种支付方式
+- 缴费记录查询:查询历史缴费记录
+- 支付结果查询:查询支付状态
+- 其他辅助功能
+
+## 技术栈
+
+- Vue 2.6.x
+- Vuex
+- Vue Router
+- Vant UI
+- Axios
+- Sass
+- ES6+
+
+## 项目结构
+
+```
+├── public/ # 静态资源目录
+├── src/ # 源代码目录
+│ ├── api/ # API接口定义
+│ ├── assets/ # 静态资源文件
+│ ├── components/ # 公共组件
+│ ├── router/ # 路由配置
+│ ├── store/ # Vuex状态管理
+│ ├── utils/ # 工具函数
+│ ├── views/ # 页面组件
+│ ├── App.vue # 根组件
+│ └── main.js # 入口文件
+├── .env.development # 开发环境配置
+├── .env.production # 生产环境配置
+├── babel.config.js # Babel配置
+├── postcss.config.js # PostCSS配置
+└── vue.config.js # Vue CLI配置
+```
+
+## 快速开始
+
+### 安装依赖
+```
+npm install
+```
+
+### 开发模式
+```
+npm run dev
+```
+
+### 生产构建
+```
+npm run build
+```
+
+### 代码格式化
+```
+npm run lint
+```
+
+## 组件说明
+
+### 主要页面组件
+
+- `Index.vue`: 在线缴费首页,显示待缴费账单列表
+- `PrepayBills.vue`: 预缴账单页面,显示未到期的预缴账单
+- `Records.vue`: 缴费记录页面,显示历史缴费记录
+- `BillDetail.vue`: 账单详情页,显示账单详细信息
+- `RecordDetail.vue`: 缴费记录详情页,显示缴费记录详细信息
+- `EnterprisePay.vue`: 公对公支付页面,提供公对公支付链接
+- `PayResult.vue`: 支付结果页面,显示支付结果信息
+
+### 公共组件
+
+- `PayerSelector.vue`: 业户选择器组件,用于选择当前操作的业户
+
+## 业务规则
+
+### 缴费流程
+
+1. 用户在账单列表页选择需要缴费的账单
+2. 选择支付方式(个对公/公对公)
+3. 系统生成支付订单
+4. 用户完成支付
+5. 系统更新账单状态和缴费记录
+
+### 公对公支付
+
+1. 用户选择公对公支付方式后,系统生成支付链接
+2. 支付链接有效期为5分钟
+3. 用户复制链接后在浏览器中打开完成支付
+4. 系统自动更新支付状态
+
+## API文档
+
+详细的API接口文档请参考后端开发文档。
\ No newline at end of file
diff --git a/h5/babel.config.js b/h5/babel.config.js
new file mode 100644
index 0000000..f707b32
--- /dev/null
+++ b/h5/babel.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ presets: [
+ '@vue/cli-plugin-babel/preset'
+ ]
+};
\ No newline at end of file
diff --git a/h5/package.json b/h5/package.json
new file mode 100644
index 0000000..f37ff90
--- /dev/null
+++ b/h5/package.json
@@ -0,0 +1,81 @@
+{
+ "name": "U-H5",
+ "version": "1.0.0",
+ "private": true,
+ "author": {
+ "name": "zzz"
+ },
+ "scripts": {
+ "dev": "vue-cli-service serve --mode development",
+ "build": "vue-cli-service build --mode production",
+ "lint": "vue-cli-service lint",
+ "lint-fix": "vue-cli-service lint ./src --ext .vue,.js",
+ "prepare": "husky install"
+ },
+ "dependencies": {
+ "@vant/area-data": "^1.2.1",
+ "axios": "^0.27.2",
+ "clipboard": "^2.0.11",
+ "echarts": "^5.5.1",
+ "file-saver": "^2.0.5",
+ "jszip": "^3.10.1",
+ "qrcode": "^1.5.3",
+ "qs": "^6.10.3",
+ "tui-image-editor": "^3.15.3",
+ "vant": "^2.13.1",
+ "vue": "^2.6.14",
+ "vue-draggable-resizable": "^2.3.0",
+ "vue-router": "^3.5.4",
+ "vue-wechat-title": "^2.0.7",
+ "vuedraggable": "^2.24.3",
+ "vuex": "^3.6.2",
+ "weixin-js-sdk": "^1.4.0-test"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.12.16",
+ "@babel/eslint-parser": "^7.12.16",
+ "@vue/cli-plugin-babel": "~5.0.0",
+ "@vue/cli-plugin-eslint": "~5.0.0",
+ "@vue/cli-service": "~5.0.0",
+ "@vue/eslint-config-airbnb": "^5.0.2",
+ "autoprefixer": "^10.4.7",
+ "babel-plugin-import": "^1.13.3",
+ "compression-webpack-plugin": "^6.1.1",
+ "core-js": "^3.23.2",
+ "eslint": "^7.32.0",
+ "eslint-config-airbnb-base": "^15.0.0",
+ "eslint-config-prettier": "^8.3.0",
+ "eslint-plugin-import": "^2.25.3",
+ "eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-vue": "^8.0.3",
+ "eslint-plugin-vuejs-accessibility": "^1.1.0",
+ "husky": "^7.0.2",
+ "lint-staged": "^11.1.2",
+ "postcss-px-to-viewport": "^1.1.1",
+ "prettier": "^2.7.1",
+ "sass": "^1.53.0",
+ "sass-loader": "^13.0.0",
+ "style-resources-loader": "^1.5.0",
+ "vue-template-compiler": "^2.6.14",
+ "webpack-bundle-analyzer": "^4.5.0"
+ },
+ "eslintConfig": {
+ "root": true,
+ "env": {
+ "node": true
+ },
+ "extends": [
+ "plugin:vue/essential",
+ "eslint:recommended"
+ ],
+ "parserOptions": {
+ "parser": "@babel/eslint-parser"
+ },
+ "rules": {}
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions",
+ "not dead"
+ ]
+}
diff --git a/h5/postcss.config.js b/h5/postcss.config.js
new file mode 100644
index 0000000..5659fd4
--- /dev/null
+++ b/h5/postcss.config.js
@@ -0,0 +1,16 @@
+module.exports = {
+ plugins: {
+ 'postcss-px-to-viewport': {
+ viewportWidth: 375, // 视窗的宽度,对应的是我们设计稿的宽度
+ viewportHeight: 667, // 视窗的高度,根据750设备的宽度来指定,一般指定1334
+ unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数
+ viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
+ selectorBlackList: ['.ignore', '.hairlines'], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
+ minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
+ mediaQuery: false // 允许在媒体查询中转换`px`
+ },
+ 'autoprefixer': {
+ browsers: ['Android >= 4.0', 'iOS >= 8']
+ }
+ }
+};
\ No newline at end of file
diff --git a/h5/public/index.html b/h5/public/index.html
new file mode 100644
index 0000000..acd7df0
--- /dev/null
+++ b/h5/public/index.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+ <%= htmlWebpackPlugin.options.title %>
+
+
+
+
+
+ We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/App.vue b/h5/src/App.vue
new file mode 100644
index 0000000..f11aedf
--- /dev/null
+++ b/h5/src/App.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/api/payment.js b/h5/src/api/payment.js
new file mode 100644
index 0000000..99f429c
--- /dev/null
+++ b/h5/src/api/payment.js
@@ -0,0 +1,50 @@
+import { request } from '@/utils/request';
+
+const api = {
+ // 查询缴费账单列表
+ getBills(params) {
+ return request.post('/payment/bills', params);
+ },
+
+ // 查询预缴账单列表
+ getPrepayBills(params) {
+ return request.post('/payment/prepay-bills', params);
+ },
+
+ // 查询账单详情
+ getBillDetail(billId, config = { showLoading: false }) {
+ return request.get(`/payment/bill-detail/${billId}`, null, config);
+ },
+
+ // 查询缴费记录
+ getPaymentRecords(params) {
+ return request.post('/payment/records', params);
+ },
+
+ // 查询缴费记录详情
+ getRecordDetail(billId, config) {
+ return request.get(`/payment/record-detail/${billId}`, null, config);
+ },
+
+ // 创建支付订单
+ createPayOrder(data) {
+ return request.post('/payment/create-order', data);
+ },
+
+ // 查询支付结果
+ queryPayResult(orderNo) {
+ return request.get(`/payment/order-result/${orderNo}`);
+ },
+
+ // 取消支付订单
+ cancelOrder(orderNo) {
+ return request.post(`/payment/cancel-order/${orderNo}`);
+ },
+
+ // 获取公对公支付链接
+ getEnterprisePayUrl(orderNo) {
+ return request.get(`/payment/enterprise-pay-url/${orderNo}`);
+ },
+};
+
+export default api;
\ No newline at end of file
diff --git a/h5/src/api/user.js b/h5/src/api/user.js
new file mode 100644
index 0000000..9a497f4
--- /dev/null
+++ b/h5/src/api/user.js
@@ -0,0 +1,15 @@
+import { request } from '@/utils/request';
+
+const api = {
+ // 获取用户信息
+ getUserInfo() {
+ return request.get('/user/info');
+ },
+
+ // 获取业户列表
+ getPayerList() {
+ return request.get('/user/payer-list');
+ },
+};
+
+export default api;
\ No newline at end of file
diff --git a/h5/src/assets/styles/index.scss b/h5/src/assets/styles/index.scss
new file mode 100644
index 0000000..e6f26d8
--- /dev/null
+++ b/h5/src/assets/styles/index.scss
@@ -0,0 +1,268 @@
+html, body {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: 100%;
+ font-size: 16px;
+ font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ background-color: #f5f5f5;
+ color: #333;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+/* 常用颜色 */
+:root {
+ --primary-color: #1989fa;
+ --success-color: #07c160;
+ --warning-color: #ff976a;
+ --danger-color: #ee0a24;
+ --info-color: #909399;
+ --background-color: #f5f5f5;
+ --text-color: #323233;
+ --text-color-light: #969799;
+ --border-color: #ebedf0;
+}
+
+/* 常用间距 */
+.m-0 { margin: 0; }
+.m-1 { margin: 4px; }
+.m-2 { margin: 8px; }
+.m-3 { margin: 12px; }
+.m-4 { margin: 16px; }
+.m-5 { margin: 20px; }
+
+.mt-0 { margin-top: 0; }
+.mt-1 { margin-top: 4px; }
+.mt-2 { margin-top: 8px; }
+.mt-3 { margin-top: 12px; }
+.mt-4 { margin-top: 16px; }
+.mt-5 { margin-top: 20px; }
+
+.mb-0 { margin-bottom: 0; }
+.mb-1 { margin-bottom: 4px; }
+.mb-2 { margin-bottom: 8px; }
+.mb-3 { margin-bottom: 12px; }
+.mb-4 { margin-bottom: 16px; }
+.mb-5 { margin-bottom: 20px; }
+
+.ml-0 { margin-left: 0; }
+.ml-1 { margin-left: 4px; }
+.ml-2 { margin-left: 8px; }
+.ml-3 { margin-left: 12px; }
+.ml-4 { margin-left: 16px; }
+.ml-5 { margin-left: 20px; }
+
+.mr-0 { margin-right: 0; }
+.mr-1 { margin-right: 4px; }
+.mr-2 { margin-right: 8px; }
+.mr-3 { margin-right: 12px; }
+.mr-4 { margin-right: 16px; }
+.mr-5 { margin-right: 20px; }
+
+.p-0 { padding: 0; }
+.p-1 { padding: 4px; }
+.p-2 { padding: 8px; }
+.p-3 { padding: 12px; }
+.p-4 { padding: 16px; }
+.p-5 { padding: 20px; }
+
+.pt-0 { padding-top: 0; }
+.pt-1 { padding-top: 4px; }
+.pt-2 { padding-top: 8px; }
+.pt-3 { padding-top: 12px; }
+.pt-4 { padding-top: 16px; }
+.pt-5 { padding-top: 20px; }
+
+.pb-0 { padding-bottom: 0; }
+.pb-1 { padding-bottom: 4px; }
+.pb-2 { padding-bottom: 8px; }
+.pb-3 { padding-bottom: 12px; }
+.pb-4 { padding-bottom: 16px; }
+.pb-5 { padding-bottom: 20px; }
+
+.pl-0 { padding-left: 0; }
+.pl-1 { padding-left: 4px; }
+.pl-2 { padding-left: 8px; }
+.pl-3 { padding-left: 12px; }
+.pl-4 { padding-left: 16px; }
+.pl-5 { padding-left: 20px; }
+
+.pr-0 { padding-right: 0; }
+.pr-1 { padding-right: 4px; }
+.pr-2 { padding-right: 8px; }
+.pr-3 { padding-right: 12px; }
+.pr-4 { padding-right: 16px; }
+.pr-5 { padding-right: 20px; }
+
+/* 常用布局类 */
+.flex {
+ display: flex;
+}
+
+.flex-column {
+ flex-direction: column;
+}
+
+.flex-wrap {
+ flex-wrap: wrap;
+}
+
+.justify-start {
+ justify-content: flex-start;
+}
+
+.justify-center {
+ justify-content: center;
+}
+
+.justify-end {
+ justify-content: flex-end;
+}
+
+.justify-between {
+ justify-content: space-between;
+}
+
+.justify-around {
+ justify-content: space-around;
+}
+
+.align-start {
+ align-items: flex-start;
+}
+
+.align-center {
+ align-items: center;
+}
+
+.align-end {
+ align-items: flex-end;
+}
+
+.flex-1 {
+ flex: 1;
+}
+
+.flex-grow-0 {
+ flex-grow: 0;
+}
+
+.flex-grow-1 {
+ flex-grow: 1;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.text-primary {
+ color: var(--primary-color);
+}
+
+.text-success {
+ color: var(--success-color);
+}
+
+.text-warning {
+ color: var(--warning-color);
+}
+
+.text-danger {
+ color: var(--danger-color);
+}
+
+.text-info {
+ color: var(--info-color);
+}
+
+.bg-white {
+ background-color: #fff;
+}
+
+.rounded {
+ border-radius: 4px;
+}
+
+.rounded-circle {
+ border-radius: 50%;
+}
+
+.truncate {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.position-relative {
+ position: relative;
+}
+
+.position-absolute {
+ position: absolute;
+}
+
+.w-100 {
+ width: 100%;
+}
+
+.h-100 {
+ height: 100%;
+}
+
+.divider {
+ height: 8px;
+ background-color: var(--background-color);
+}
+
+/* 标题样式 */
+.page-title {
+ font-size: 18px;
+ font-weight: 500;
+ padding: 12px 16px;
+ border-bottom: 1px solid var(--border-color);
+ background-color: #fff;
+ margin: 0;
+}
+
+/* 自定义卡片样式 */
+.card {
+ background-color: #fff;
+ border-radius: 8px;
+ margin: 12px;
+ padding: 16px;
+ box-shadow: 0 2px 12px rgba(100, 101, 102, 0.08);
+}
+
+.card-title {
+ font-size: 16px;
+ font-weight: 500;
+ margin: 0 0 12px 0;
+ padding-bottom: 8px;
+ border-bottom: 1px solid var(--border-color);
+}
+
+/* 底部操作栏 */
+.footer-action-bar {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 100;
+ background-color: #fff;
+ padding: 10px 16px;
+ border-top: 1px solid var(--border-color);
+ box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
+}
\ No newline at end of file
diff --git a/h5/src/assets/styles/variables.scss b/h5/src/assets/styles/variables.scss
new file mode 100644
index 0000000..5b213b7
--- /dev/null
+++ b/h5/src/assets/styles/variables.scss
@@ -0,0 +1,101 @@
+// 主题颜色
+$primary-color: #1989fa;
+$success-color: #07c160;
+$warning-color: #ff976a;
+$danger-color: #ee0a24;
+$info-color: #909399;
+
+// 背景颜色
+$background-color: #f5f5f5;
+$background-color-light: #fafafa;
+
+// 文字颜色
+$text-color: #323233;
+$text-color-light: #969799;
+$text-color-disabled: #c8c9cc;
+
+// 边框颜色
+$border-color: #ebedf0;
+$border-color-dark: #dcdee0;
+
+// 字体大小
+$font-size-xs: 10px;
+$font-size-sm: 12px;
+$font-size-md: 14px;
+$font-size-lg: 16px;
+$font-size-xl: 18px;
+
+// 边距
+$padding-xs: 4px;
+$padding-sm: 8px;
+$padding-md: 12px;
+$padding-lg: 16px;
+$padding-xl: 20px;
+
+// 圆角
+$border-radius-sm: 2px;
+$border-radius-md: 4px;
+$border-radius-lg: 8px;
+$border-radius-max: 999px;
+
+// 动画
+$animation-duration-base: 0.3s;
+$animation-duration-fast: 0.2s;
+$animation-timing-function-enter: ease-out;
+$animation-timing-function-leave: ease-in;
+
+// 阴影
+$shadow-1: 0 2px 4px rgba(0, 0, 0, 0.1);
+$shadow-2: 0 4px 8px rgba(0, 0, 0, 0.1);
+$shadow-3: 0 8px 16px rgba(0, 0, 0, 0.1);
+
+// 混合器
+@mixin ellipsis {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+@mixin multi-ellipsis($lines) {
+ display: -webkit-box;
+ -webkit-line-clamp: $lines;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+@mixin hairline-bottom($color: $border-color) {
+ position: relative;
+
+ &::after {
+ position: absolute;
+ box-sizing: border-box;
+ content: ' ';
+ pointer-events: none;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ border-bottom: 1px solid $color;
+ transform: scaleY(0.5);
+ }
+}
+
+@mixin flex-center {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+@mixin flex-between {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+@mixin clearfix {
+ &::after {
+ content: '';
+ display: table;
+ clear: both;
+ }
+}
\ No newline at end of file
diff --git a/h5/src/components/PayerSelector.vue b/h5/src/components/PayerSelector.vue
new file mode 100644
index 0000000..3ad3d88
--- /dev/null
+++ b/h5/src/components/PayerSelector.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/env.development.js b/h5/src/env.development.js
new file mode 100644
index 0000000..17a94f7
--- /dev/null
+++ b/h5/src/env.development.js
@@ -0,0 +1,10 @@
+// 开发环境配置
+export default {
+ NODE_ENV: 'development',
+
+ // API 基础路径
+ BASE_API: '/api',
+
+ // 页面标题
+ TITLE: '在线缴费系统'
+};
\ No newline at end of file
diff --git a/h5/src/env.production.js b/h5/src/env.production.js
new file mode 100644
index 0000000..ae5db72
--- /dev/null
+++ b/h5/src/env.production.js
@@ -0,0 +1,10 @@
+// 生产环境配置
+export default {
+ NODE_ENV: 'production',
+
+ // API 基础路径
+ BASE_API: '/api',
+
+ // 页面标题
+ TITLE: '在线缴费系统'
+};
\ No newline at end of file
diff --git a/h5/src/main.js b/h5/src/main.js
new file mode 100644
index 0000000..0f786af
--- /dev/null
+++ b/h5/src/main.js
@@ -0,0 +1,25 @@
+import Vue from 'vue';
+import App from './App.vue';
+import router from './router';
+import store from './store';
+
+// 完整引入Vant及其样式
+import Vant from 'vant';
+import 'vant/lib/index.css';
+
+Vue.use(Vant);
+
+// 导入全局样式
+import './assets/styles/index.scss';
+
+// 全局API请求
+import { request } from './utils/request';
+Vue.prototype.$http = request;
+
+Vue.config.productionTip = false;
+
+new Vue({
+ router,
+ store,
+ render: (h) => h(App),
+}).$mount('#app');
\ No newline at end of file
diff --git a/h5/src/router/index.js b/h5/src/router/index.js
new file mode 100644
index 0000000..f1b7245
--- /dev/null
+++ b/h5/src/router/index.js
@@ -0,0 +1,75 @@
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+import VueWechatTitle from 'vue-wechat-title';
+
+Vue.use(VueRouter);
+Vue.use(VueWechatTitle);
+
+// 路由懒加载
+const routes = [
+ {
+ path: '/',
+ redirect: '/payment',
+ },
+ {
+ path: '/payment',
+ name: 'Payment',
+ component: () => import('../views/payment/Index.vue'),
+ meta: { title: '在线缴费' },
+ },
+ {
+ path: '/payment/prepay',
+ name: 'PrepayBills',
+ component: () => import('../views/payment/PrepayBills.vue'),
+ meta: { title: '预缴账单' },
+ },
+ {
+ path: '/payment/records',
+ name: 'PaymentRecords',
+ component: () => import('../views/payment/Records.vue'),
+ meta: { title: '缴费记录' },
+ },
+ {
+ path: '/payment/bill-detail/:billId',
+ name: 'BillDetail',
+ component: () => import('../views/payment/BillDetail.vue'),
+ meta: { title: '账单详情' },
+ },
+ {
+ path: '/payment/record-detail/:billId',
+ name: 'RecordDetail',
+ component: () => import('../views/payment/RecordDetail.vue'),
+ meta: { title: '缴费详情' },
+ },
+ {
+ path: '/payment/pay-result',
+ name: 'PayResult',
+ component: () => import('../views/payment/PayResult.vue'),
+ meta: { title: '支付结果' },
+ },
+ {
+ path: '/payment/enterprise-pay',
+ name: 'EnterprisePay',
+ component: () => import('../views/payment/EnterprisePay.vue'),
+ meta: { title: '公对公支付' },
+ },
+ {
+ path: '*',
+ redirect: '/payment',
+ },
+];
+
+const router = new VueRouter({
+ routes,
+});
+
+// 全局路由守卫
+router.beforeEach((to, from, next) => {
+ // 更新页面标题
+ if (to.meta.title) {
+ document.title = to.meta.title;
+ }
+ next();
+});
+
+export default router;
\ No newline at end of file
diff --git a/h5/src/store/index.js b/h5/src/store/index.js
new file mode 100644
index 0000000..0865de4
--- /dev/null
+++ b/h5/src/store/index.js
@@ -0,0 +1,26 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import payment from './modules/payment';
+import user from './modules/user';
+
+Vue.use(Vuex);
+
+export default new Vuex.Store({
+ state: {
+ loading: false,
+ },
+ mutations: {
+ SET_LOADING(state, loading) {
+ state.loading = loading;
+ },
+ },
+ actions: {
+ setLoading({ commit }, loading) {
+ commit('SET_LOADING', loading);
+ },
+ },
+ modules: {
+ payment,
+ user,
+ },
+});
\ No newline at end of file
diff --git a/h5/src/store/modules/payment.js b/h5/src/store/modules/payment.js
new file mode 100644
index 0000000..530379a
--- /dev/null
+++ b/h5/src/store/modules/payment.js
@@ -0,0 +1,217 @@
+import { Toast } from 'vant';
+import api from '@/api/payment';
+
+const state = {
+ bills: [], // 缴费账单列表
+ prepayBills: [], // 预缴账单列表
+ paymentRecords: [], // 缴费记录
+ currentBill: null, // 当前查看的账单详情
+ selectedBills: [], // 已选择的账单
+ totalAmount: 0, // 总金额
+ totalCount: 0, // 总数量
+ payerName: '', // 缴费人姓名
+ buildingGroups: [], // 楼宇分组
+ payType: 'personal', // 支付类型:personal-个对公,enterprise-公对公
+};
+
+const mutations = {
+ SET_BILLS(state, data) {
+ state.bills = data.bills || [];
+ state.totalAmount = data.totalAmount || 0;
+ state.totalCount = data.totalCount || 0;
+ state.payerName = data.payerName || '';
+ state.buildingGroups = data.buildingGroups || [];
+ },
+ SET_PREPAY_BILLS(state, data) {
+ state.prepayBills = data.bills || [];
+ state.totalAmount = data.totalAmount || 0;
+ state.totalCount = data.totalCount || 0;
+ state.payerName = data.payerName || '';
+ state.buildingGroups = data.buildingGroups || [];
+ },
+ SET_PAYMENT_RECORDS(state, records) {
+ state.paymentRecords = records;
+ },
+ SET_CURRENT_BILL(state, bill) {
+ state.currentBill = bill;
+ },
+ ADD_SELECTED_BILL(state, bill) {
+ // 保留已选择的其他费用类型账单,但替换同一费用类型下的账单
+ const existingBillsFromOtherTypes = state.selectedBills.filter(item =>
+ item.feeTypeName !== bill.feeTypeName ||
+ item.buildingId !== bill.buildingId
+ );
+
+ // 将当前账单加入到已选择的账单列表中
+ state.selectedBills = [...existingBillsFromOtherTypes, bill];
+ },
+ REMOVE_SELECTED_BILL(state, billId) {
+ state.selectedBills = state.selectedBills.filter(bill => bill.billId !== billId);
+ },
+ CLEAR_SELECTED_BILLS(state) {
+ state.selectedBills = [];
+ },
+ SET_PAY_TYPE(state, type) {
+ state.payType = type;
+ },
+};
+
+const actions = {
+ // 获取缴费账单列表
+ async getBills({ commit }, params) {
+ try {
+ const response = await api.getBills(params);
+ if (response.code === '0000000000000000') {
+ commit('SET_BILLS', response.data);
+ return response.data;
+ } else {
+ Toast.fail(response.message || '获取账单列表失败');
+ return null;
+ }
+ } catch (error) {
+ Toast.fail('获取账单列表失败');
+ return null;
+ }
+ },
+
+ // 获取预缴账单列表
+ async getPrepayBills({ commit }, params) {
+ try {
+ const response = await api.getPrepayBills(params);
+ if (response.code === '0000000000000000') {
+ commit('SET_PREPAY_BILLS', response.data);
+ return response.data;
+ } else {
+ Toast.fail(response.message || '获取预缴账单列表失败');
+ return null;
+ }
+ } catch (error) {
+ Toast.fail('获取预缴账单列表失败');
+ return null;
+ }
+ },
+
+ // 获取缴费记录
+ async getPaymentRecords({ commit }, params) {
+ try {
+ const response = await api.getPaymentRecords(params);
+ if (response.code === '0000000000000000') {
+ commit('SET_PAYMENT_RECORDS', response.data.list || []);
+ return response.data;
+ } else {
+ Toast.fail(response.message || '获取缴费记录失败');
+ return null;
+ }
+ } catch (error) {
+ Toast.fail('获取缴费记录失败');
+ return null;
+ }
+ },
+
+ // 获取账单详情
+ async getBillDetail({ commit }, billId) {
+ try {
+ const response = await api.getBillDetail(billId);
+ if (response.code === '0000000000000000') {
+ commit('SET_CURRENT_BILL', response.data);
+ return response.data;
+ } else {
+ Toast.fail(response.message || '获取账单详情失败');
+ return null;
+ }
+ } catch (error) {
+ Toast.fail('获取账单详情失败');
+ return null;
+ }
+ },
+
+ // 获取缴费记录详情
+ async getRecordDetail({ commit }, billId) {
+ try {
+ const response = await api.getRecordDetail(billId);
+ if (response.code === '0000000000000000') {
+ commit('SET_CURRENT_BILL', response.data);
+ return response.data;
+ } else {
+ Toast.fail(response.message || '获取缴费记录详情失败');
+ return null;
+ }
+ } catch (error) {
+ Toast.fail('获取缴费记录详情失败');
+ return null;
+ }
+ },
+
+ // 创建支付订单
+ async createPayOrder({ state }) {
+ if (state.selectedBills.length === 0) {
+ Toast.fail('请选择需要缴费的账单');
+ return null;
+ }
+
+ try {
+ const billIds = state.selectedBills.map(bill => bill.billId);
+ const payType = state.payType;
+
+ const response = await api.createPayOrder({
+ billIds,
+ payType,
+ });
+
+ if (response.code === '0000000000000000') {
+ return response.data;
+ } else {
+ Toast.fail(response.message || '创建支付订单失败');
+ return null;
+ }
+ } catch (error) {
+ Toast.fail('创建支付订单失败');
+ return null;
+ }
+ },
+
+ // 查询支付结果
+ async queryPayResult({ commit }, orderNo) {
+ try {
+ const response = await api.queryPayResult(orderNo);
+ return response.data;
+ } catch (error) {
+ Toast.fail('查询支付结果失败');
+ return null;
+ }
+ },
+
+ // 取消订单
+ async cancelOrder(_, orderNo) {
+ try {
+ const response = await api.cancelOrder(orderNo);
+ if (response.code === '0000000000000000') {
+ Toast.success('取消订单成功');
+ return true;
+ } else {
+ Toast.fail(response.message || '取消订单失败');
+ return false;
+ }
+ } catch (error) {
+ Toast.fail('取消订单失败');
+ return false;
+ }
+ },
+};
+
+const getters = {
+ selectedBillsTotalAmount(state) {
+ return state.selectedBills.reduce((total, bill) => total + bill.totalNeedAmount, 0);
+ },
+ selectedBillsCount(state) {
+ return state.selectedBills.length;
+ },
+};
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+ getters,
+};
\ No newline at end of file
diff --git a/h5/src/store/modules/user.js b/h5/src/store/modules/user.js
new file mode 100644
index 0000000..6d36663
--- /dev/null
+++ b/h5/src/store/modules/user.js
@@ -0,0 +1,107 @@
+import { Toast } from 'vant';
+import api from '@/api/user';
+
+const state = {
+ userInfo: null, // 用户信息
+ currentPayer: null, // 当前选择的业户
+ payerList: [], // 业户列表
+};
+
+const mutations = {
+ SET_USER_INFO(state, userInfo) {
+ state.userInfo = userInfo;
+ },
+ SET_CURRENT_PAYER(state, payer) {
+ state.currentPayer = payer;
+ // 将当前选择的业户ID保存到localStorage
+ if (payer) {
+ localStorage.setItem('currentPayerId', payer.id);
+ } else {
+ localStorage.removeItem('currentPayerId');
+ }
+ },
+ SET_PAYER_LIST(state, list) {
+ state.payerList = list;
+ },
+};
+
+const actions = {
+ // 获取用户信息
+// async getUserInfo({ commit }) {
+// try {
+// const response = await api.getUserInfo();
+// if (response.code === '0000000000000000') {
+// commit('SET_USER_INFO', response.data);
+// return response.data;
+// } else {
+// Toast.fail(response.message || '获取用户信息失败');
+// return null;
+// }
+// } catch (error) {
+// Toast.fail('获取用户信息失败');
+// return null;
+// }
+// },
+
+// // 获取业户列表
+// async getPayerList({ commit }) {
+// try {
+// const response = await api.getPayerList();
+// if (response.code === '0000000000000000') {
+// const payerList = response.data || [];
+// commit('SET_PAYER_LIST', payerList);
+
+// // 如果localStorage中有保存的业户ID,则自动选择
+// const savedPayerId = localStorage.getItem('currentPayerId');
+// if (savedPayerId && payerList.length > 0) {
+// const savedPayer = payerList.find(payer => payer.id === Number(savedPayerId));
+// if (savedPayer) {
+// commit('SET_CURRENT_PAYER', savedPayer);
+// } else {
+// // 如果没找到保存的业户,则选择第一个
+// commit('SET_CURRENT_PAYER', payerList[0]);
+// }
+// } else if (payerList.length > 0) {
+// // 默认选择第一个业户
+// commit('SET_CURRENT_PAYER', payerList[0]);
+// }
+
+// return payerList;
+// } else {
+// Toast.fail(response.message || '获取业户列表失败');
+// return [];
+// }
+// } catch (error) {
+// Toast.fail('获取业户列表失败');
+// return [];
+// }
+// },
+
+// // 选择业户
+// selectPayer({ commit }, payer) {
+// commit('SET_CURRENT_PAYER', payer);
+// },
+};
+
+const getters = {
+ // 当前选择的业户ID
+ currentPayerId(state) {
+ return state.currentPayer ? state.currentPayer.id : null;
+ },
+ // 当前选择的业户名称
+ currentPayerName(state) {
+ return state.currentPayer ? state.currentPayer.name : '';
+ },
+ // 是否已选择业户
+ hasSelectedPayer(state) {
+ return !!state.currentPayer;
+ },
+};
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+ getters,
+};
\ No newline at end of file
diff --git a/h5/src/utils/request.js b/h5/src/utils/request.js
new file mode 100644
index 0000000..9f69d01
--- /dev/null
+++ b/h5/src/utils/request.js
@@ -0,0 +1,164 @@
+import axios from 'axios';
+import { Toast } from 'vant';
+import qs from 'qs';
+import store from '@/store';
+
+// 创建axios实例
+const service = axios.create({
+ baseURL: 'http://192.168.137.45:8080',
+ timeout: 30000,
+ headers: {
+ 'Content-Type': 'application/json;charset=utf-8',
+ },
+});
+
+// 请求拦截器
+service.interceptors.request.use(
+ (config) => {
+ // 显示loading,除非请求配置中指定了不显示
+ if (config.showLoading !== false) {
+ store.dispatch('setLoading', true);
+ }
+
+ // 获取token
+ const token = localStorage.getItem('token');
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+
+ // 如果有选择业户,则在请求头中带上业户ID
+ const currentPayerId = store.getters['user/currentPayerId'];
+ if (currentPayerId) {
+ config.headers['X-Payer-Id'] = currentPayerId;
+ }
+
+ // 处理GET请求参数
+ if (config.method === 'get' && config.params) {
+ config.paramsSerializer = (params) => {
+ return qs.stringify(params, { arrayFormat: 'repeat' });
+ };
+ }
+
+ return config;
+ },
+ (error) => {
+ // 隐藏loading
+ store.dispatch('setLoading', false);
+ return Promise.reject(error);
+ }
+);
+
+// 响应拦截器
+service.interceptors.response.use(
+ (response) => {
+ // 隐藏loading
+ store.dispatch('setLoading', false);
+
+ // 处理二进制数据
+ if (response.config.responseType === 'blob') {
+ return response;
+ }
+
+ const res = response.data;
+
+ // 判断是否成功
+ if (res.code === '0000000000000000') {
+ return res;
+ }
+
+ // 处理业务错误
+ if (res.code === 'UNAUTHORIZED') {
+ // 未登录,跳转到登录页
+ Toast.fail('用户未登录或登录已过期');
+ localStorage.removeItem('token');
+ setTimeout(() => {
+ window.location.href = '/login';
+ }, 1500);
+ } else {
+ // 其他业务错误
+ Toast.fail(res.message || '请求失败');
+ }
+
+ return res;
+ },
+ (error) => {
+ // 隐藏loading
+ store.dispatch('setLoading', false);
+
+ let message = '请求失败';
+ if (error.response) {
+ switch (error.response.status) {
+ case 401:
+ message = '用户未登录或登录已过期';
+ localStorage.removeItem('token');
+ setTimeout(() => {
+ window.location.href = '/login';
+ }, 1500);
+ break;
+ case 403:
+ message = '拒绝访问';
+ break;
+ case 404:
+ message = '请求地址错误';
+ break;
+ case 500:
+ message = '服务器内部错误';
+ break;
+ default:
+ message = `请求失败(${error.response.status})`;
+ }
+ } else if (error.message.includes('timeout')) {
+ message = '请求超时';
+ }
+
+ Toast.fail(message);
+ return Promise.reject(error);
+ }
+);
+
+// 封装请求方法
+export const request = {
+ get(url, params, config = {}) {
+ return service({
+ url,
+ method: 'get',
+ params,
+ ...config
+ });
+ },
+ post(url, data, config = {}) {
+ return service({
+ url,
+ method: 'post',
+ data,
+ ...config
+ });
+ },
+ put(url, data, config = {}) {
+ return service({
+ url,
+ method: 'put',
+ data,
+ ...config
+ });
+ },
+ delete(url, params, config = {}) {
+ return service({
+ url,
+ method: 'delete',
+ params,
+ ...config
+ });
+ },
+ download(url, params, config = {}) {
+ return service({
+ url,
+ method: 'get',
+ params,
+ responseType: 'blob',
+ ...config
+ });
+ },
+};
+
+export default service;
\ No newline at end of file
diff --git a/h5/src/views/payment/BillDetail.vue b/h5/src/views/payment/BillDetail.vue
new file mode 100644
index 0000000..085640f
--- /dev/null
+++ b/h5/src/views/payment/BillDetail.vue
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
基本信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
账单明细
+
+
+
+
+ {{ detail.billDetailType == '0' ? '原账单' : '滞纳金' }}
+
+
+
{{ detail.feTypeName || '未知费用类型' }}
+
¥{{ formatAmount(detail.billAmount || 0) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/views/payment/EnterprisePay.vue b/h5/src/views/payment/EnterprisePay.vue
new file mode 100644
index 0000000..97b35db
--- /dev/null
+++ b/h5/src/views/payment/EnterprisePay.vue
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+
¥{{ formatAmount(amount) }}
+
+ 链接有效期:
+
+
+
+
+
+
支付链接
+
+
+
温馨提示:
+
1. 该链接5分钟内有效,请尽快完成支付
+
2. 复制链接后可粘贴至浏览器地址栏打开
+
3. 支付成功后,系统将自动处理订单
+
+
+
+
+ 返回
+ 查询支付结果
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/views/payment/Index.vue b/h5/src/views/payment/Index.vue
new file mode 100644
index 0000000..4f13720
--- /dev/null
+++ b/h5/src/views/payment/Index.vue
@@ -0,0 +1,619 @@
+
+
+
在线缴费
+
+
+
+
+ 缴费人:
+ {{ payerName }}
+
+
缴费记录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
应收日期: {{ bill.pybDt }}
+
+
¥{{ formatAmount(bill.totalNeedAmount) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 个对公缴费
+
+
个人对公司支付,通过微信/支付宝等方式
+
+
+
+ 公对公缴费
+
+
公司对公司支付,通过银行转账方式
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/views/payment/PayResult.vue b/h5/src/views/payment/PayResult.vue
new file mode 100644
index 0000000..bd03b27
--- /dev/null
+++ b/h5/src/views/payment/PayResult.vue
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
支付成功
+
¥{{ formatAmount(amount) }}
+
+
订单编号:{{ orderNo }}
+
支付时间:{{ formatDateTime() }}
+
+
+
+
+
+
+
支付处理中
+
¥{{ formatAmount(amount) }}
+
+
订单编号:{{ orderNo }}
+
请耐心等待,支付结果处理中...
+
+
+
+
+
+
+
支付失败
+
¥{{ formatAmount(amount) }}
+
+
订单编号:{{ orderNo }}
+
支付未完成,请重新支付
+
+
+
+
+
+
+
支付已关闭
+
¥{{ formatAmount(amount) }}
+
+
订单编号:{{ orderNo }}
+
该订单已关闭,请重新发起支付
+
+
+
+
+
+
+
状态未知
+
¥{{ formatAmount(amount) }}
+
+
订单编号:{{ orderNo }}
+
无法获取支付状态,请稍后查询
+
+
+
+
+
+
+ 刷新支付结果
+
+ 重新支付
+
+ 返回缴费页面
+
+ 查看缴费记录
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/views/payment/PrepayBills.vue b/h5/src/views/payment/PrepayBills.vue
new file mode 100644
index 0000000..270b43d
--- /dev/null
+++ b/h5/src/views/payment/PrepayBills.vue
@@ -0,0 +1,602 @@
+
+
+
+
+
+
+ 缴费人:
+ {{ payerName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
应收日期: {{ bill.pybDt }}
+
+
¥{{ formatAmount(bill.totalNeedAmount) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 个对公缴费
+
+
个人对公司支付,通过微信/支付宝等方式
+
+
+
+ 公对公缴费
+
+
公司对公司支付,通过银行转账方式
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/views/payment/RecordDetail.vue b/h5/src/views/payment/RecordDetail.vue
new file mode 100644
index 0000000..4070c20
--- /dev/null
+++ b/h5/src/views/payment/RecordDetail.vue
@@ -0,0 +1,286 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
¥{{ formatAmount(getPaymentAmount()) }}
+
+
+
+
+
基本信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
账单明细
+
+
+
+
+ {{ detail.billDetailType === '0' ? '原账单' : '滞纳金' }}
+
+
+
{{ detail.feTypeName || '未知费用类型' }}
+
¥{{ formatAmount(detail.billAmount || 0) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/src/views/payment/Records.vue b/h5/src/views/payment/Records.vue
new file mode 100644
index 0000000..2f619ed
--- /dev/null
+++ b/h5/src/views/payment/Records.vue
@@ -0,0 +1,378 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
应收日期: {{ record.pybDt }}
+
+
+
¥{{ formatAmount(record.paymentAmt) }}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/h5/vue.config.js b/h5/vue.config.js
new file mode 100644
index 0000000..6398338
--- /dev/null
+++ b/h5/vue.config.js
@@ -0,0 +1,71 @@
+const { defineConfig } = require('@vue/cli-service');
+
+module.exports = defineConfig({
+ // 部署应用包时的基本 URL
+ publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
+
+ // 当运行 vue-cli-service build 时生成的生产环境构建文件的目录
+ outputDir: 'dist',
+
+ // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录
+ assetsDir: 'static',
+
+ // 指定生成的 index.html 的输出路径 (相对于 outputDir)
+ indexPath: 'index.html',
+
+ // 默认情况下,生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存
+ filenameHashing: true,
+
+ // 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
+ lintOnSave: process.env.NODE_ENV !== 'production',
+
+ // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建
+ productionSourceMap: false,
+
+ // 开发服务器配置
+ devServer: {
+ host: '0.0.0.0',
+ port: 8080,
+ open: true,
+ // proxy: {
+ // // 配置跨域
+ // '/': {
+ // target: 'http://192.168.137.45:8080',
+ // changeOrigin: true,
+ // pathRewrite: {
+ // '^/api': ''
+ // }
+ // }
+ // }
+ },
+
+ // CSS相关配置
+ css: {
+ // 是否使用css分离插件 ExtractTextPlugin
+ extract: process.env.NODE_ENV === 'production',
+ // 开启 CSS source maps?
+ sourceMap: false,
+ // css预设器配置项
+ loaderOptions: {
+ sass: {
+ // 全局引入变量和 mixin
+ additionalData: `
+ @import "@/assets/styles/variables.scss";
+ `
+ }
+ }
+ },
+
+ // webpack配置
+ configureWebpack: {
+ // 配置 webpack 压缩
+ optimization: {
+ minimize: process.env.NODE_ENV === 'production'
+ }
+ },
+
+ // 第三方插件配置
+ pluginOptions: {
+ // ...
+ }
+});
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..c496ed7
--- /dev/null
+++ b/package.json
@@ -0,0 +1,10 @@
+{
+ "dependencies": {
+ "element-china-area-data": "^6.1.0",
+ "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
new file mode 100644
index 0000000..2754fd2
--- /dev/null
+++ b/pc/.env.development
@@ -0,0 +1,4 @@
+NODE_ENV = 'development'
+
+# 开发环境API地址
+VUE_APP_BASE_API = http://192.168.137.45:8080
\ No newline at end of file
diff --git a/pc/.env.production b/pc/.env.production
new file mode 100644
index 0000000..6465c6f
--- /dev/null
+++ b/pc/.env.production
@@ -0,0 +1,4 @@
+NODE_ENV = 'production'
+
+# 生产环境API地址
+VUE_APP_BASE_API = http://192.168.137.3:8080/api
\ No newline at end of file
diff --git a/pc/.gitignore b/pc/.gitignore
new file mode 100644
index 0000000..f71b978
--- /dev/null
+++ b/pc/.gitignore
@@ -0,0 +1,10 @@
+node_modules/
+.DS_Store
+.idea/
+.vscode/
+.env
+.env.local
+
+
+package-lock.json
+yarn.lock
diff --git a/pc/package.json b/pc/package.json
new file mode 100644
index 0000000..19dea53
--- /dev/null
+++ b/pc/package.json
@@ -0,0 +1,81 @@
+{
+ "name": "yoaf-web",
+ "version": "1.1.2",
+ "description": "智慧教育平台",
+ "author": "front-end",
+ "license": "MIT",
+ "scripts": {
+ "dev": "vue-cli-service serve",
+ "build:prod": "vue-cli-service build",
+ "build:stage": "vue-cli-service build --mode staging",
+ "preview": "node build/index.js --preview"
+ },
+ "keywords": [
+ "vue",
+ "admin",
+ "dashboard",
+ "element-ui",
+ "boilerplate",
+ "admin-template",
+ "management-system"
+ ],
+ "dependencies": {
+ "@riophae/vue-treeselect": "^0.4.0",
+ "axios": "0.24.0",
+ "clipboard": "2.0.8",
+ "core-js": "3.19.1",
+ "dayjs": "^1.11.10",
+ "echarts": "4.9.0",
+ "element-ui": "^2.15.6",
+ "file-saver": "2.0.5",
+ "fuse.js": "6.4.3",
+ "highlight.js": "9.18.5",
+ "html2canvas": "^1.4.1",
+ "js-beautify": "1.13.0",
+ "js-cookie": "3.0.1",
+ "jszip": "^3.10.1",
+ "moment": "^2.30.1",
+ "nprogress": "0.2.0",
+ "qrcode": "^1.5.3",
+ "qrcode.vue": "^3.6.0",
+ "quill": "1.3.7",
+ "screenfull": "5.0.2",
+ "sm-crypto": "^0.3.12",
+ "sortablejs": "1.10.2",
+ "tui-image-editor": "^3.15.3",
+ "vue": "^2.7.14",
+ "vue-count-to": "1.0.13",
+ "vue-cropper": "0.5.5",
+ "vue-meta": "2.4.0",
+ "vue-router": "3.4.9",
+ "vuedraggable": "^2.24.3",
+ "vuex": "3.6.0",
+ "xlsx": "^0.18.5",
+ "element-china-area-data": "^6.1.0",
+ "mammoth": "^1.9.0"
+ },
+ "devDependencies": {
+ "@vue/cli-plugin-babel": "4.4.6",
+ "@vue/cli-service": "4.4.6",
+ "babel-loader": "^10.0.0",
+ "babel-plugin-dynamic-import-node": "2.3.3",
+ "chalk": "4.1.0",
+ "compression-webpack-plugin": "5.0.2",
+ "connect": "3.6.6",
+ "mockjs": "^1.0.1-beta3",
+ "runjs": "4.4.2",
+ "sass": "1.32.13",
+ "sass-loader": "10.1.1",
+ "script-ext-html-webpack-plugin": "2.1.5",
+ "svg-sprite-loader": "5.1.1",
+ "vue-template-compiler": "2.6.14"
+ },
+ "engines": {
+ "node": ">=8.9",
+ "npm": ">= 3.0.0"
+ },
+ "browserslist": [
+ ">1%",
+ "last 2 versions"
+ ]
+}
diff --git a/pc/public.zip b/pc/public.zip
new file mode 100644
index 0000000..028483f
Binary files /dev/null and b/pc/public.zip differ
diff --git a/pc/public/index.html b/pc/public/index.html
new file mode 100644
index 0000000..a66625c
--- /dev/null
+++ b/pc/public/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ 智慧教育平台
+
+
+
+ We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/App.vue b/pc/src/App.vue
new file mode 100644
index 0000000..4194d3c
--- /dev/null
+++ b/pc/src/App.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/api/asset/classification.js b/pc/src/api/asset/classification.js
new file mode 100644
index 0000000..eb64c9e
--- /dev/null
+++ b/pc/src/api/asset/classification.js
@@ -0,0 +1,110 @@
+import request from '@/utils/request'
+
+// 查询资产分类列表
+export function listClassification(query) {
+ return request({
+ url: '/asset/classifications/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询资产分类详情
+export function getClassification(id) {
+ return request({
+ url: '/asset/classifications/' + id,
+ method: 'get'
+ })
+}
+
+// 新增资产分类
+export function addClassification(data) {
+ return request({
+ url: '/asset/classifications/create',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改资产分类
+export function updateClassification(data) {
+ return request({
+ url: '/asset/classifications/update/' + data.id,
+ method: 'post',
+ data: data
+ })
+}
+
+// 删除资产分类
+export function delClassification(id, lastModUserId) {
+ return request({
+ url: '/asset/classifications/delete/' + id,
+ method: 'post',
+ params: lastModUserId ? { lastModUserId } : {}
+ })
+}
+
+// 禁用资产分类
+export function disableClassification(id, lastModUserId) {
+ return request({
+ url: '/asset/classifications/' + id + '/status/disable',
+ method: 'post',
+ params: lastModUserId ? { lastModUserId } : {}
+ })
+}
+
+// 启用资产分类
+export function enableClassification(id, lastModUserId) {
+ return request({
+ url: '/asset/classifications/' + id + '/status/enable',
+ method: 'post',
+ params: lastModUserId ? { lastModUserId } : {}
+ })
+}
+
+// 批量删除资产分类
+export function delClassificationBatch(ids, lastModUserId) {
+ return request({
+ url: '/asset/classifications/deleteBatch',
+ method: 'post',
+ data: ids,
+ params: lastModUserId ? { lastModUserId } : {}
+ })
+}
+
+// 获取资产分类树形结构
+export function getClassificationTree(query) {
+ return request({
+ url: '/asset/classifications/tree',
+ method: 'get',
+ params: query
+ })
+}
+
+// 根据父ID查询子分类
+export function getChildClassifications(parentId, query) {
+
+ return request({
+ url: '/asset/classifications/children/' + parentId,
+ method: 'get',
+ params: query
+ })
+}
+
+// 检查分类是否被使用
+export function checkClassificationInUse(id) {
+ return request({
+ url: '/asset/classifications/' + id + '/check',
+ method: 'get'
+ })
+}
+
+// 导出资产分类
+export function exportClassification(query) {
+
+ return request({
+ url: '/asset/classifications/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/pc/src/api/asset/inventory.js b/pc/src/api/asset/inventory.js
new file mode 100644
index 0000000..848a80d
--- /dev/null
+++ b/pc/src/api/asset/inventory.js
@@ -0,0 +1,136 @@
+import request from '@/utils/request'
+
+// 获取资产列表
+export function listAssets(query) {
+ return request({
+ url: '/asset/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 获取资产详情
+export function getAsset(assetCode) {
+ return request({
+ url: `/asset/${assetCode}`,
+ method: 'get',
+ })
+}
+
+// 新增资产
+export function addAsset(data) {
+ return request({
+ url: '/asset/create',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改资产
+export function updateAsset(data) {
+ return request({
+ url: `/asset/update/${data.assetCode}`,
+ method: 'post',
+ data: data
+ })
+}
+
+// 删除资产
+export function deleteAsset(assetCode) {
+ return request({
+ url: '/asset/delete',
+ method: 'post',
+ params: { assetCode }
+ })
+}
+
+// 批量删除资产
+export function deleteAssets(assetCodes) {
+ return request({
+ url: '/asset/batch/delete',
+ method: 'post',
+ data: { assetCodes }
+ })
+}
+
+// 导出资产
+export function exportAsset(query) {
+ return request({
+ url: '/asset/export',
+ method: 'get',
+ params: query,
+ responseType: 'blob'
+ })
+}
+
+// 下载资产导入模板
+export function downloadTemplate() {
+ return request({
+ url: '/asset/template/download',
+ method: 'get',
+ responseType: 'blob'
+ })
+}
+
+// 获取资产位置树
+export function listAssetLocationTree() {
+ return request({
+ url: '/asset/location/tree',
+ method: 'get'
+ })
+}
+
+// 获取公司列表
+export function listCompanies() {
+ return request({
+ url: '/admin/company/getAllCompanyDetails',
+ method: 'get'
+ })
+}
+
+// 获取用户列表
+export function listUsers() {
+ return request({
+ url: '/v1/member/list',
+ method: 'get',
+ })
+}
+
+// 上传资产图片
+export function uploadAssetImage(data) {
+ return request({
+ url: '/asset/upload/image',
+ method: 'post',
+ data: data
+ })
+}
+
+/**
+ * 批量打印资产标签
+ * @param {Array} assetCodes 资产编码数组
+ * @returns {Object} 请求结果
+ */
+export function printAssetLabels(assetCodes) {
+ return request({
+ url: '/asset/print',
+ method: 'post',
+ data: assetCodes
+ })
+}
+
+// 检查资产编码是否存在
+export function checkAssetCode(code) {
+ return request({
+ url: '/asset/check/code',
+ method: 'get',
+ params: { code }
+ })
+}
+
+// 获取标签配置
+export function getLabelConfig() {
+ return request({
+ url: '/asset/label',
+ method: 'get'
+ })
+}
\ No newline at end of file
diff --git a/pc/src/api/asset/label.js b/pc/src/api/asset/label.js
new file mode 100644
index 0000000..0971a09
--- /dev/null
+++ b/pc/src/api/asset/label.js
@@ -0,0 +1,110 @@
+import request from '@/utils/request'
+
+// 查询资产标签列表
+export function listLabelTemplates(query) {
+ return request({
+ url: '/asset/label/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 获取标签模板详情
+export function getLabelTemplate(id) {
+ return request({
+ url: '/asset/label/template/' + id,
+ method: 'get'
+ })
+}
+
+// 新增资产标签
+export function addLabelTemplate(data) {
+ return request({
+ url: '/asset/label/create',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改资产标签
+export function updateLabelTemplate(id, data) {
+ return request({
+ url: '/asset/label/update' + id,
+ method: 'post',
+ data: data
+ })
+}
+
+// 删除标签模板
+export function deleteLabelTemplate(id) {
+ return request({
+ url: '/asset/label/template/' + id,
+ method: 'post'
+ })
+}
+
+// 设置默认模板
+export function setDefaultTemplate(id) {
+ return request({
+ url: '/asset/label/template/default/' + id,
+ method: 'post'
+ })
+}
+
+// 获取可用的标签字段
+export function getLabelFields() {
+ const fieldData = [
+ { id: 1, name: '资产名称' },
+ { id: 2, name: '资产分类' },
+ { id: 3, name: '资产编码' },
+ { id: 4, name: '资产位置' },
+ { id: 5, name: '品牌' },
+ { id: 6, name: '型号' },
+ { id: 7, name: '设备序列号' },
+ { id: 8, name: '管理员' },
+ { id: 9, name: '保养到期时间' },
+ { id: 10, name: '保养说明' },
+ { id: 11, name: '使用部门' }
+ ];
+
+ return Promise.resolve({
+ code: '0000000000000000',
+ msg: 'success',
+ data: fieldData
+ });
+}
+
+// 获取字段对应的示例值
+export function getFieldSampleValues() {
+ return {
+ '1': 'ThinkPad笔记本',
+ '2': '电脑/笔记本电脑',
+ '3': 'ASSET-001',
+ '4': '研发部-A区',
+ '5': 'Lenovo',
+ '6': 'X1 Carbon',
+ '7': 'SN12345678',
+ '8': '张三',
+ '9': '2024-12-31',
+ '10': '每季度保养一次',
+ '11': '研发部'
+ };
+}
+
+// 打印标签预览
+export function previewLabel(data) {
+ return request({
+ url: '/asset/label/preview',
+ method: 'post',
+ data: data
+ })
+}
+
+// 打印标签
+export function printLabel(data) {
+ return request({
+ url: '/asset/label/print',
+ method: 'post',
+ data: data
+ })
+}
\ No newline at end of file
diff --git a/pc/src/api/asset/location.js b/pc/src/api/asset/location.js
new file mode 100644
index 0000000..d36e242
--- /dev/null
+++ b/pc/src/api/asset/location.js
@@ -0,0 +1,120 @@
+import request from '@/utils/request'
+
+// 查询资产位置列表
+export function listLocation(query) {
+ return request({
+ url: '/asset/locations/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询资产位置详情
+export function getLocation(id) {
+ return request({
+ url: '/asset/locations/' + id,
+ method: 'get'
+ })
+}
+
+// 新增资产位置
+export function addLocation(data) {
+ return request({
+ url: '/asset/locations/create',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改资产位置
+export function updateLocation(data) {
+ return request({
+ url: '/asset/locations/update/' + data.id,
+ method: 'post',
+ data: data
+ })
+}
+
+// 删除资产位置
+export function delLocation(id, lastModUserId) {
+ return request({
+ url: '/asset/locations/delete/' + id,
+ method: 'post',
+ params: lastModUserId ? { lastModUserId } : {}
+ })
+}
+
+// 禁用资产位置
+export function disableLocation(id, lastModUserId) {
+ return request({
+ url: '/asset/locations/' + id + '/status/disable',
+ method: 'post',
+ params: lastModUserId ? { lastModUserId } : {}
+ })
+}
+
+// 启用资产位置
+export function enableLocation(id, lastModUserId) {
+ return request({
+ url: '/asset/locations/' + id + '/status/enable',
+ method: 'post',
+ params: lastModUserId ? { lastModUserId } : {}
+ })
+}
+
+// 批量删除资产位置
+export function delLocationBatch(ids, lastModUserId) {
+ return request({
+ url: '/asset/locations/batch/delete',
+ method: 'post',
+ data: ids,
+ params: lastModUserId ? { lastModUserId } : {}
+ })
+}
+
+// 获取资产位置树形结构
+export function getLocationTree(query) {
+ return request({
+ url: '/asset/locations/tree',
+ method: 'get',
+ params: query
+ })
+}
+
+// 根据父ID查询子位置
+export function getChildLocations(parentId, query) {
+ return request({
+ url: '/asset/locations/children/' + parentId,
+ method: 'get',
+ params: query
+ })
+}
+
+// 检查位置是否被使用
+export function checkLocationInUse(id) {
+ return request({
+ url: '/asset/locations/' + id + '/check',
+ method: 'get'
+ })
+}
+
+// 检查编码唯一性
+export function checkLocationCode(id, locationCode) {
+ return request({
+ url: '/asset/locations/check/code',
+ method: 'get',
+ params: {
+ id: id,
+ locationCode: locationCode
+ }
+ })
+}
+
+// 导出资产位置
+export function exportLocation(query) {
+ return request({
+ url: '/asset/locations/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/pc/src/api/bak/merchant/index.js b/pc/src/api/bak/merchant/index.js
new file mode 100644
index 0000000..68df39a
--- /dev/null
+++ b/pc/src/api/bak/merchant/index.js
@@ -0,0 +1,7 @@
+// 导出所有子模块
+export * from './lead'
+
+// 未来可以添加其他子模块,如:
+// export * from './team'
+// export * from './personnel'
+// 等等
\ No newline at end of file
diff --git a/pc/src/api/bak/merchant/lead.js b/pc/src/api/bak/merchant/lead.js
new file mode 100644
index 0000000..67f447c
--- /dev/null
+++ b/pc/src/api/bak/merchant/lead.js
@@ -0,0 +1,151 @@
+import request from '@/utils/request'
+
+// 线索状态API
+export function getLeadStatusList() {
+ return request({
+ url: '/bizLead/status/list',
+ method: 'get'
+ })
+}
+
+export function getLeadStatusDetail(id) {
+ return request({
+ url: `/bizLead/status/${id}`,
+ method: 'get'
+ })
+}
+
+export function addLeadStatus(data) {
+ return request({
+ url: '/bizLead/status',
+ method: 'post',
+ data
+ })
+}
+
+export function updateLeadStatus(data) {
+ return request({
+ url: '/bizLead/status',
+ method: 'put',
+ data
+ })
+}
+
+export function deleteLeadStatus(id, userId) {
+ return request({
+ url: `/bizLead/status/${id}`,
+ method: 'delete',
+ params: { userId }
+ })
+}
+
+export function checkLeadStatusName(statusName) {
+ return request({
+ url: '/bizLead/status/checkName',
+ method: 'get',
+ params: { statusName }
+ })
+}
+
+// 线索管理API
+export function getLeadList(params) {
+ return request({
+ url: '/bizLead/list',
+ method: 'get',
+ params
+ })
+}
+
+export function getMyLeadList(params) {
+ return request({
+ url: '/bizLead/myLeads',
+ method: 'get',
+ params
+ })
+}
+
+export function getAllLeadList(params) {
+ return request({
+ url: '/bizLead/allLeads',
+ method: 'get',
+ params
+ })
+}
+
+export function getPublicLeadList(params) {
+ return request({
+ url: '/bizLead/publicLeads',
+ method: 'get',
+ params
+ })
+}
+
+export function getLeadDetail(id) {
+ return request({
+ url: `/bizLead/${id}`,
+ method: 'get'
+ })
+}
+
+export function addLead(data) {
+ return request({
+ url: '/bizLead',
+ method: 'post',
+ data
+ })
+}
+
+export function updateLead(data) {
+ return request({
+ url: '/bizLead',
+ method: 'put',
+ data
+ })
+}
+
+export function changeLeadStatus(id, statusId, userId) {
+ return request({
+ url: `/bizLead/${id}/status`,
+ method: 'put',
+ params: { statusId, userId }
+ })
+}
+
+export function changeLeadPersonnel(id, personnelId, userId) {
+ return request({
+ url: `/bizLead/${id}/personnel`,
+ method: 'put',
+ params: { personnelId, userId }
+ })
+}
+
+export function checkLeadPhone(phone) {
+ return request({
+ url: '/bizLead/checkPhone',
+ method: 'get',
+ params: { phone }
+ })
+}
+
+export function convertLeadToIntention(id, userId) {
+ return request({
+ url: `/bizLead/${id}/convert`,
+ method: 'post',
+ params: { userId }
+ })
+}
+
+export function deleteLead(id, userId) {
+ return request({
+ url: `/bizLead/${id}`,
+ method: 'delete',
+ params: { userId }
+ })
+}
+
+export function getLeadFollowHistory(leadId) {
+ return request({
+ url: `/bizLead/${leadId}/followHistory`,
+ method: 'get'
+ })
+}
\ No newline at end of file
diff --git a/pc/src/api/building.js b/pc/src/api/building.js
new file mode 100644
index 0000000..872224a
--- /dev/null
+++ b/pc/src/api/building.js
@@ -0,0 +1,140 @@
+import request from '@/utils/request'
+
+// 查询楼宇列表
+export function getBuildingList(query) {
+ return request({
+ url: '/room/building/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询楼宇详细
+export function getBuildingDetail(id) {
+ return request({
+ url: `/room/building/${id}`,
+ method: 'get'
+ })
+}
+
+// 新增楼宇
+export function addBuilding(data) {
+ // 处理字段名映射,确保前端驼峰命名与后端下划线命名正确对应
+ const processedData = {
+ ...data,
+ buildingTags: data.buildingTags,
+ isHot: data.isHot,
+ imageUrl: data.buildingImage,
+ }
+
+ // 删除undefined的属性
+ Object.keys(processedData).forEach(key => {
+ if (processedData[key] === undefined) {
+ delete processedData[key]
+ }
+ })
+
+ return request({
+ url: '/room/building/add',
+ method: 'post',
+ data: processedData
+ })
+}
+
+// 修改楼宇
+export function updateBuilding(data) {
+ // 处理字段名映射,确保前端驼峰命名与后端下划线命名正确对应
+ const processedData = {
+ ...data,
+ buildingTags: data.buildingTags,
+ isHot: data.isHot,
+ imageUrl: data.buildingImage
+ }
+
+ // 删除undefined的属性
+ Object.keys(processedData).forEach(key => {
+ if (processedData[key] === undefined) {
+ delete processedData[key]
+ }
+ })
+
+ return request({
+ url: '/room/building/edit',
+ method: 'post',
+ data: processedData
+ })
+}
+
+// 删除楼宇
+export function deleteBuilding(ids) {
+ return request({
+ url: `/room/building/remove/${ids}`,
+ method: 'get'
+ })
+}
+
+// 获取楼宇统计信息
+export function getBuildingStatistics(id) {
+ return request({
+ url: `/room/building/${id}/statistics`,
+ method: 'get'
+ })
+}
+
+// 查询楼层列表
+export function getFloorList(query) {
+ return request({
+ url: `/room/floor/list/${query}`,
+ method: 'get'
+ })
+}
+
+// 获取楼层详情
+export function getFloorDetail(id) {
+ return request({
+ url: `/room/floor/${id}`,
+ method: 'get'
+ })
+}
+
+// 新增楼层
+export function addFloor(data) {
+ return request({
+ url: '/room/floor/add',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改楼层
+export function updateFloor(data) {
+ return request({
+ url: '/room/floor/edit',
+ method: 'post',
+ data: data
+ })
+}
+
+// 删除楼层
+export function deleteFloor(ids) {
+ return request({
+ url: `/room/floor/remove/${ids}`,
+ method: 'get'
+ })
+}
+
+// 根据楼宇ID获取楼层列表
+export function getFloorListByBuilding(buildingId) {
+ return request({
+ url: `/room/floor/building/${buildingId}`,
+ method: 'get'
+ })
+}
+
+// 收支账号管理
+export function getAllAccounts() {
+ return request({
+ url: `/admin/account/getAllAccounts`,
+ method: 'get'
+ })
+}
\ No newline at end of file
diff --git a/pc/src/api/finance.js b/pc/src/api/finance.js
new file mode 100644
index 0000000..d180721
--- /dev/null
+++ b/pc/src/api/finance.js
@@ -0,0 +1,925 @@
+import request from '@/utils/request'
+
+// 费用分类管理接口
+export function getFeeCategories(query) {
+ return request({
+ url: '/finance/category/page',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getAllFeeCategories() {
+ return request({
+ url: '/finance/category/list',
+ method: 'get'
+ })
+}
+
+export function getFeeCategory(id) {
+ return request({
+ url: `/finance/category/${id}`,
+ method: 'get'
+ })
+}
+
+export function addFeeCategory(data) {
+ return request({
+ url: '/finance/category',
+ method: 'post',
+ data
+ })
+}
+
+export function updateFeeCategory(id, data) {
+ return request({
+ url: `/finance/category/${id}`,
+ method: 'put',
+ data
+ })
+}
+
+export function deleteFeeCategory(id) {
+ return request({
+ url: `/finance/category/${id}`,
+ method: 'delete'
+ })
+}
+
+// 费用类型管理接口
+export function getFeeTypes(query) {
+ return request({
+ url: '/finance/type/page',
+ method: 'get',
+ params: query
+ })
+}
+
+export function getFeeTypesByCategory(categoryId) {
+ return request({
+ url: `/finance/type/list/${categoryId}`,
+ method: 'get'
+ })
+}
+
+export function getFeeType(id) {
+ return request({
+ url: `/finance/type/${id}`,
+ method: 'get'
+ })
+}
+
+export function addFeeType(data) {
+ return request({
+ url: '/finance/type',
+ method: 'post',
+ data
+ })
+}
+
+export function updateFeeType(id, data) {
+ return request({
+ url: `/finance/type/${id}`,
+ method: 'put',
+ data
+ })
+}
+
+export function deleteFeeType(id) {
+ return request({
+ 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'
+ })
+}
+
+/* 收费标准相关接口 */
+
+// 分页查询收费标准列表
+export function getChargingStandardPage(query) {
+ return request({
+ url: '/finance/charging-standard/page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 根据ID查询收费标准详情
+export function getChargingStandardById(id) {
+ return request({
+ url: `/finance/charging-standard/${id}`,
+ method: 'get'
+ })
+}
+
+// 新增收费标准
+export function addChargingStandard(data) {
+ return request({
+ url: '/finance/charging-standard',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改收费标准
+export function updateChargingStandard(data) {
+ return request({
+ url: '/finance/charging-standard',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除收费标准
+export function deleteChargingStandard(id) {
+ return request({
+ url: `/finance/charging-standard/${id}`,
+ method: 'delete'
+ })
+}
+
+// 更新收费标准状态(立即失效)
+export function updateChargingStandardStatus(id) {
+ return request({
+ url: `/finance/charging-standard/${id}/updateStatus`,
+ method: 'put'
+ })
+}
+
+// 检查收费标准名称是否存在
+export function checkChargingStandardName(standardName, id) {
+ return request({
+ url: '/finance/charging-standard/check-name',
+ method: 'get',
+ params: { standardName, id }
+ })
+}
+
+// 根据状态查询收费标准列表
+export function getChargingStandardListByStatus(status) {
+ return request({
+ url: '/finance/charging-standard/list-by-status',
+ method: 'get',
+ params: { status }
+ })
+}
+
+// 获取费用类型树
+export function getFeeTypeTree(params) {
+ return request({
+ url: '/feeForeign/categories',
+ method: 'get',
+ params
+ })
+}
+
+// 预览账单
+export function previewBill(data) {
+ return request({
+ url: '/finance/charging-standard/bill/preview',
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ data
+ })
+}
+
+// 生成账单
+export function generateBill(data) {
+ return request({
+ url: '/finance/charging-standard/bill/generate',
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ data
+ })
+}
+
+/**
+ * 分页查询账单-收费标准关联表数据
+ * @param {Object} data - 查询参数
+ * @returns {Promise} - 返回Promise对象
+ */
+export function getBillChargingStandardRelPage(data) {
+ return request({
+ url: '/finance/bill-charging-standard-rel/page',
+ method: 'post',
+ data
+ })
+}
+
+/**
+ * 获取特定标准ID的绑定房间账单列表
+ * @param {string} standardId 收费标准ID
+ */
+export function getBillsByStandardId(standardId) {
+ return request({
+ url: `/finance/bill-charging-standard-rel/${standardId}/bills`,
+ method: 'get'
+ })
+}
+
+// 账单管理接口
+export function addBill(data) {
+ return request({
+ url: '/bill/add',
+ method: 'post',
+ data
+ })
+}
+
+export function getBillList(data) {
+ return request({
+ url: '/bill/list',
+ method: 'post',
+ data
+ })
+}
+
+export function getBillDetail(billId) {
+ return request({
+ url: `/bill/detail/${billId}`,
+ method: 'get'
+ })
+}
+
+export function uploadBillAttachment(billId, file) {
+ const formData = new FormData()
+ formData.append('billId', billId)
+ formData.append('file', file)
+ return request({
+ url: '/bill/upload-attachment',
+ method: 'post',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+// 账单附件删除
+export function deleteBillAttachment(attachmentId) {
+ return request({
+ url: `/bill/attachment/delete/${attachmentId}`,
+ method: 'get'
+ })
+}
+
+export function getBillAttachmentList(billId) {
+ return request({
+ url: `/bill/attachment/list/${billId}`,
+ method: 'get'
+ })
+}
+
+export function exportBillList(data) {
+ return request({
+ url: '/bill/export',
+ method: 'post',
+ data,
+ responseType: 'blob'
+ })
+}
+
+// 收支流水相关接口
+export function getTransactionList(params) {
+ return request({
+ url: '/finance/transaction/page',
+ method: 'get',
+ params
+ })
+}
+
+export function getTransactionDetail(id) {
+ return request({
+ url: `/finance/transaction/${id}`,
+ method: 'get'
+ })
+}
+
+export function addTransaction(data) {
+ return request({
+ url: '/finance/transaction',
+ method: 'post',
+ data
+ })
+}
+
+export function updateTransaction(data) {
+ return request({
+ url: '/finance/transaction',
+ method: 'put',
+ data
+ })
+}
+
+export function exportTransactionList(params) {
+ return request({
+ url: '/finance/transaction/export',
+ method: 'get',
+ params,
+ responseType: 'blob'
+ })
+}
+
+export function getTransactionAttachments(transactionId) {
+ return request({
+ url: `/finance/transaction/${transactionId}`,
+ method: 'get'
+ })
+}
+
+export function uploadTransactionAttachment(transactionId, file) {
+ const formData = new FormData()
+ formData.append('transactionId', transactionId)
+ formData.append('userId', localStorage.getItem('userId') || '')
+ formData.append('userName', localStorage.getItem('userName') || '')
+ formData.append('file', file)
+
+ return request({
+ url: '/finance/transaction/attachment',
+ method: 'post',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+export function deleteTransactionAttachment(attachmentId) {
+ return request({
+ url: `/finance/transaction/attachment/file/${attachmentId}`,
+ method: 'delete'
+ })
+}
+
+export function previewAttachment(attachmentId) {
+ return request({
+ url: `/finance/transaction/attachment/preview/file/${attachmentId}`,
+ method: 'get',
+ responseType: 'blob'
+ })
+}
+
+export function previewAttachmentByFileId(fileId) {
+ return request({
+ url: `/finance/transaction/attachment/preview/file/${fileId}`,
+ method: 'get',
+ responseType: 'blob'
+ })
+}
+
+export function downloadAttachment(fileId, fileName) {
+ return request({
+ url: `/finance/transaction/attachment/download/${fileId}`,
+ method: 'get',
+ params: { fileName },
+ responseType: 'blob'
+ })
+}
+
+export function deleteAttachmentByFileId(fileId) {
+ return request({
+ url: `/finance/transaction/attachment/file/${fileId}`,
+ method: 'delete',
+ params: {
+ userId: localStorage.getItem('userId') || ''
+ }
+ })
+}
+
+export function addTransactionOperation(data) {
+ return request({
+ url: '/finance/transaction/operation',
+ method: 'post',
+ data
+ })
+}
+
+export function getTransactionOperationLogs(transactionId, query) {
+ return request({
+ url: `/finance/transaction/${transactionId}`,
+ method: 'get'
+ })
+}
+
+// 获取所有收支账户
+export function getAllFinanceAccounts() {
+ return request({
+ url: '/finance/account/list',
+ method: 'get'
+ })
+}
+
+// 获取流水账户级联选项
+export function getAccountCascaderOptions() {
+ return request({
+ url: '/finance/account/cascader',
+ method: 'get'
+ })
+}
+
+// 账单调整相关接口
+
+// 添加账单调整(按金额或按比例)
+export function addBillAdjustment(data) {
+ return request({
+ url: '/v1/bill-adjustments',
+ method: 'post',
+ data
+ })
+}
+
+// 调整账单滞纳金专用接口
+export function adjustLateFee(data) {
+ return request({
+ url: '/v1/late-fees/adjust',
+ method: 'post',
+ data
+ })
+}
+
+// 结算账单滞纳金接口
+export function settleLateFee(data) {
+ return request({
+ url: '/v1/late-fees/settle',
+ method: 'post',
+ data
+ })
+}
+
+// 作废账单调整
+export function voidBillAdjustment(data) {
+ return request({
+ url: '/v1/bill-adjustments/void',
+ method: 'put',
+ data
+ })
+}
+
+// 分页查询账单调整记录
+export function getBillAdjustmentList(params) {
+ return request({
+ url: '/v1/bill-adjustments',
+ method: 'get',
+ params
+ })
+}
+
+// 获取账单调整详情
+export function getBillAdjustmentDetail(id) {
+ return request({
+ url: `/v1/bill-adjustments/${id}`,
+ method: 'get'
+ })
+}
+
+// 上传账单调整附件
+export function uploadBillAdjustmentAttachment(id, file) {
+ const formData = new FormData()
+ formData.append('file', file)
+ return request({
+ url: `/v1/bill-adjustments/${id}/attachments`,
+ method: 'post',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+// 删除账单调整附件
+export function deleteBillAdjustmentAttachment(attachmentId) {
+ return request({
+ url: `/v1/bill-adjustments/attachments/${attachmentId}`,
+ method: 'delete'
+ })
+}
+
+// 获取账单明细
+export function getBillDetailById(detailId) {
+ return request({
+ url: `/v1/bill-details/${detailId}`,
+ method: 'get'
+ })
+}
+
+// 获取账单调整附件列表
+export function getBillAdjustmentAttachmentList(adjustmentId) {
+ return request({
+ url: `/v1/bill-adjustments/attachments/view/${adjustmentId}`,
+ method: 'get'
+ })
+}
+
+// 获取账单操作记录
+export function getBillOperationRecords(billId, params) {
+ return request({
+ url: `/v1/operation-records/list/${billId}`,
+ method: 'get',
+ params
+ })
+}
+
+// 账单支付相关接口
+// 提交账单支付
+export function submitBillPayment(data) {
+ return request({
+ url: '/v1/bill-payments',
+ method: 'post',
+ data
+ })
+}
+
+// 分页查询支付记录
+export function getBillPaymentRecords(params) {
+ return request({
+ url: '/v1/bill-payments',
+ method: 'get',
+ params
+ })
+}
+
+// 获取支付详情
+export function getBillPaymentDetail(id) {
+ return request({
+ url: `/v1/bill-payments/${id}`,
+ method: 'get'
+ })
+}
+
+// 上传支付附件
+export function uploadBillPaymentAttachment(id, file) {
+ const formData = new FormData()
+ formData.append('file', file)
+ return request({
+ url: `/v1/bill-payments/${id}/attachments`,
+ method: 'post',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+// 删除支付附件
+export function deleteBillPaymentAttachment(attachmentId) {
+ return request({
+ url: `/v1/bill-payments/attachments/${attachmentId}`,
+ method: 'delete'
+ })
+}
+
+// 收据记录相关接口
+export function getReceiptRecordPage(params) {
+ return request({
+ url: '/finance/receipt/page',
+ method: 'get',
+ params
+ })
+}
+
+// 获取账单关联的收支流水列表
+export function getBillTransactionList(billId, params) {
+ return request({
+ url: `/v1/bill/${billId}/transactions`,
+ method: 'get',
+ params
+ })
+}
+
+export function getReceiptRecordDetail(id) {
+ return request({
+ url: `/finance/receipt/${id}`,
+ method: 'get'
+ })
+}
+
+export function voidReceipt(id) {
+ return request({
+ url: `/finance/receipt/void/${id}`,
+ method: 'post'
+ })
+}
+
+export function generateReceipt(data) {
+ return request({
+ url: '/finance/receipt/generate',
+ method: 'post',
+ data
+ })
+}
+
+export function previewReceipt(previewId) {
+ return request({
+ url: `/finance/receipt/preview/${previewId}`,
+ method: 'get',
+ responseType: 'blob'
+ })
+}
+
+export function downloadReceipt(previewId) {
+ return request({
+ url: `/finance/receipt/download-preview/${previewId}`,
+ method: 'get',
+ responseType: 'blob'
+ })
+}
+
+export function printReceipt(previewId) {
+ return request({
+ url: `/finance/receipt/print/${previewId}`,
+ method: 'get',
+ responseType: 'blob'
+ })
+}
+
+export function downloadReceiptByFilename(receiptFileName) {
+ return request({
+ url: '/finance/receipt/download-by-filename',
+ method: 'get',
+ params: { receiptFileName },
+ responseType: 'blob'
+ })
+}
+
+export function previewReceiptByFilename(receiptFileName) {
+ return request({
+ url: '/finance/receipt/preview-by-filename',
+ method: 'get',
+ params: { receiptFileName },
+ responseType: 'blob'
+ })
+}
+
+export function printReceiptByFilename(receiptFileName) {
+ return request({
+ url: '/finance/receipt/print-by-filename',
+ method: 'get',
+ params: { receiptFileName },
+ responseType: 'blob'
+ })
+}
+
+// 关闭账单
+export function closeBill(data) {
+ return request({
+ url: '/bill/close',
+ method: 'post',
+ data
+ })
+}
+
+// 获取可开据收据明细
+export function getReceiptDetails(billId) {
+ return request({
+ url: '/receipt/details',
+ method: 'get',
+ params: { billId }
+ })
+}
+
+// 开具收据
+export function issueReceipt(data) {
+ return request({
+ url: '/receipt/issue',
+ method: 'post',
+ data
+ })
+}
+
+// 分页查询收据记录
+export function getReceiptRecords(billId, params) {
+ return request({
+ url: '/receipt/records',
+ method: 'get',
+ params: { billId, ...params }
+ })
+}
+
+// 获取收据详情
+export function getReceiptDetail(id) {
+ return request({
+ url: '/receipt/detail',
+ method: 'get',
+ params: { id }
+ })
+}
+
+// 更新收据状态为已发出
+export function updateReceiptIssueStatus(id) {
+ return request({
+ url: '/receipt/issue-status',
+ method: 'post',
+ data: { id }
+ })
+}
+
+// 作废收据
+export function voidReceiptById(id) {
+ return request({
+ url: '/receipt/void',
+ method: 'post',
+ data: { id }
+ })
+}
+
+// 获取支付方式选项
+export function getPaymentMethodOptions() {
+ return request({
+ url: '/receipt/payment-methods',
+ method: 'get'
+ })
+}
+
+// 获取收据状态选项
+export function getReceiptStatusOptions() {
+ return request({
+ url: '/receipt/status-options',
+ method: 'get'
+ })
+}
+
+// 获取下一个收据编号
+export function getNextReceiptNumberByRuleId(ruleId) {
+ return request({
+ url: `/receipt/number/next/${ruleId}`,
+ method: 'get'
+ })
+}
+
+// 批量获取收据编号
+export function getBatchReceiptNumbersByRuleId(ruleId, count) {
+ return request({
+ url: `/receipt/numbers/${ruleId}/${count}`,
+ method: 'get'
+ })
+}
\ No newline at end of file
diff --git a/pc/src/api/inventory.js b/pc/src/api/inventory.js
new file mode 100644
index 0000000..98b1e47
--- /dev/null
+++ b/pc/src/api/inventory.js
@@ -0,0 +1,29 @@
+import request from '@/utils/request'
+
+/**
+ * 导入库存
+ * @param {Object} data 文件数据
+ * @returns {Object} 请求结果
+ */
+export function importInventory(data) {
+ return request({
+ url: '/inventory/import',
+ method: 'post',
+ data: data,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+/**
+ * 下载库存导入模板
+ * @returns {Object} 请求结果
+ */
+export function downloadInventoryTemplate() {
+ return request({
+ url: '/inventory/template/download',
+ method: 'get',
+ responseType: 'blob'
+ })
+}
\ 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..bcc6bcd
--- /dev/null
+++ b/pc/src/api/merchant.js
@@ -0,0 +1,583 @@
+import request from '@/utils/request'
+
+// 招商团队相关API
+export function getMerchantTeamList(params) {
+ return request({
+ url: '/bizTeam/list',
+ method: 'get',
+ params
+ })
+}
+
+export function getMerchantTeamDetail(id) {
+ return request({
+ url: `/bizTeam/${id}`,
+ method: 'get'
+ })
+}
+// 根据项目ID获取招商团队信息
+export function getMerchantTeamByProjectId(projectId) {
+ return request({
+ url: `/bizTeam/project/${projectId}`,
+ method: 'get'
+ })
+}
+
+export function addMerchantTeam(data) {
+ return request({
+ url: '/bizTeam',
+ method: 'post',
+ data
+ })
+}
+
+export function updateMerchantTeam(data) {
+ return request({
+ url: '/bizTeam',
+ method: 'put',
+ data
+ })
+}
+
+export function deleteMerchantTeam(id, userId) {
+ return request({
+ url: `/bizTeam/${id}`,
+ method: 'delete',
+ params: { userId }
+ })
+}
+
+export function checkTeamName(params) {
+ return request({
+ url: '/bizTeam/checkName',
+ method: 'get',
+ params
+ })
+}
+
+export function getProjectsList() {
+ return request({
+ url: '/bizTeam/projects',
+ method: 'get'
+ })
+}
+
+// 招商人员相关API
+export function getMerchantPersonnelList(data) {
+ return request({
+ url: '/bizPersonnel/queryAllPersonnel',
+ method: 'post',
+ data
+ })
+}
+
+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: '/bizPersonnel',
+ method: 'post',
+ data
+ })
+}
+
+export function batchAddMerchantPersonnel(data) {
+ return request({
+ url: '/bizPersonnel/batch',
+ method: 'post',
+ data
+ })
+}
+
+export function removeMerchantPersonnel(id, userId) {
+ return request({
+ url: `/bizPersonnel/${id}`,
+ method: 'delete',
+ params: { userId }
+ })
+}
+
+export function checkMemberExists(params) {
+ return request({
+ url: '/bizPersonnel/checkMember',
+ method: 'get',
+ params
+ })
+}
+
+// 成员管理相关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
+ })
+}
+
+// 线索状态API
+export function getLeadStatusList() {
+ return request({
+ url: '/bizLead/status/list',
+ method: 'get'
+ })
+}
+
+export function getLeadStatusDetail(id) {
+ return request({
+ url: `/bizLead/status/${id}`,
+ method: 'get'
+ })
+}
+
+export function addLeadStatus(data) {
+ return request({
+ url: '/bizLead/status',
+ method: 'post',
+ data
+ })
+}
+
+export function updateLeadStatus(data) {
+ return request({
+ url: '/bizLead/status',
+ method: 'put',
+ data
+ })
+}
+
+export function deleteLeadStatus(id, userId) {
+ return request({
+ url: `/bizLead/status/${id}`,
+ method: 'delete',
+ params: { userId }
+ })
+}
+
+export function checkLeadStatusName(statusName) {
+ return request({
+ url: '/bizLead/status/checkName',
+ method: 'get',
+ params: { statusName }
+ })
+}
+
+// 线索管理API
+export function getLeadList(params) {
+ return request({
+ url: '/bizLead/list',
+ method: 'get',
+ params
+ })
+}
+
+export function getMyLeadList(params) {
+ return request({
+ url: '/bizLead/myLeads',
+ method: 'get',
+ params
+ })
+}
+
+export function getAllLeadList(params) {
+ return request({
+ url: '/bizLead/allLeads',
+ method: 'get',
+ params
+ })
+}
+
+export function getPublicLeadList(params) {
+ return request({
+ url: '/bizLead/publicLeads',
+ method: 'get',
+ params
+ })
+}
+
+export function getLeadDetail(id) {
+ return request({
+ url: `/bizLead/${id}`,
+ method: 'get'
+ })
+}
+
+export function addLead(data) {
+ return request({
+ url: '/bizLead',
+ method: 'post',
+ data
+ })
+}
+
+export function updateLead(data) {
+ return request({
+ url: '/bizLead',
+ method: 'put',
+ data
+ })
+}
+
+export function changeLeadStatus(id, statusId, userId) {
+ return request({
+ url: `/bizLead/${id}/status`,
+ method: 'put',
+ params: { statusId, userId }
+ })
+}
+
+export function changeLeadPersonnel(id, personnelId, userId) {
+ return request({
+ url: `/bizLead/${id}/personnel`,
+ method: 'put',
+ params: { personnelId, userId }
+ })
+}
+
+export function checkLeadPhone(phone) {
+ return request({
+ url: '/bizLead/checkPhone',
+ method: 'get',
+ params: { phone }
+ })
+}
+
+export function convertLeadToIntention(id, userId) {
+ return request({
+ url: `/bizLead/${id}/convert`,
+ method: 'post',
+ params: { userId }
+ })
+}
+
+export function deleteLead(id, userId) {
+ return request({
+ url: `/bizLead/${id}`,
+ method: 'delete',
+ params: { userId }
+ })
+}
+
+export function getLeadFollowHistory(leadId) {
+ return request({
+ url: `/bizLead/${leadId}/followHistory`,
+ method: 'get'
+ })
+}
+
+// 意向客户相关API
+export function getCustomerDetail(id) {
+ return request({
+ url: `/bizCustomer/${id}`,
+ method: 'get'
+ })
+}
+
+export function createCustomer(data) {
+ return request({
+ url: '/bizCustomer',
+ method: 'post',
+ data
+ })
+}
+
+export function updateCustomer(data) {
+ return request({
+ url: '/bizCustomer',
+ method: 'put',
+ data
+ })
+}
+
+export function deleteCustomer(id) {
+ return request({
+ url: `/bizCustomer/${id}`,
+ method: 'delete'
+ })
+}
+
+export function changeCustomerPersonnel(id, personnelId) {
+ return request({
+ url: `/bizCustomer/personnel/${id}/${personnelId}`,
+ method: 'put'
+ })
+}
+
+export function changeCustomerStatus(id, statusId) {
+ return request({
+ url: `/bizCustomer/status/${id}/${statusId}`,
+ method: 'put'
+ })
+}
+
+export function checkCustomerPhone(params) {
+ return request({
+ url: '/bizCustomer/checkPhone',
+ method: 'get',
+ params
+ })
+}
+
+export function getMyCustomerList(data) {
+ return request({
+ url: '/bizCustomer/myCustomer',
+ method: 'post',
+ data
+ })
+}
+
+export function getAllCustomerList(data) {
+ return request({
+ url: '/bizCustomer/allCustomer',
+ method: 'post',
+ data
+ })
+}
+
+export function getPublicCustomerList(data) {
+ return request({
+ url: '/bizCustomer/publicCustomer',
+ method: 'post',
+ data
+ })
+}
+
+export function followCustomer(data) {
+ return request({
+ url: '/bizCustomer/follow',
+ method: 'post',
+ data
+ })
+}
+
+export function getCustomerFollowHistory(customerId) {
+ return request({
+ url: `/bizCustomer/followHistory/${customerId}`,
+ method: 'get'
+ })
+}
+
+export function assignCustomer(id, params) {
+ return request({
+ url: `/bizCustomer/${id}/assign`,
+ method: 'post',
+ params
+ })
+}
+
+export function returnCustomerToPublic(id, userId) {
+ return request({
+ url: `/bizCustomer/returnToPublic/${id}`,
+ method: 'post',
+ params: { userId }
+ })
+}
+
+export function getCustomerTagGroups() {
+ return request({
+ url: '/bizCustomer/tags/groups',
+ method: 'get'
+ })
+}
+
+export function saveCustomerTags(data) {
+ return request({
+ url: '/bizCustomer/tags',
+ method: 'post',
+ data
+ })
+}
+
+// 获取客户状态列表
+export function getCustomerStatusList() {
+ return request({
+ url: '/bizCustomer/status/list',
+ method: 'get'
+ })
+}
diff --git a/pc/src/api/project.js b/pc/src/api/project.js
new file mode 100644
index 0000000..5878920
--- /dev/null
+++ b/pc/src/api/project.js
@@ -0,0 +1,70 @@
+import request from '@/utils/request'
+
+// 获取项目列表
+export function getProjectList(query) {
+ return request({
+ url: '/room/project/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 获取项目详情
+export function getProjectDetail(id) {
+ return request({
+ url: `/room/project/${id}`,
+ method: 'get'
+ })
+}
+
+// 新增项目
+export function addProject(data) {
+ return request({
+ url: '/room/project/add',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改项目
+export function updateProject(id, data) {
+ const updateData = { ...data, id }
+ return request({
+ url: '/room/project/edit',
+ method: 'post',
+ data: updateData
+ })
+}
+
+// 删除项目
+export function deleteProject(id) {
+ return request({
+ url: `/room/project/remove/${id}`,
+ method: 'post'
+ })
+}
+
+// 获取项目统计数据
+export function getProjectStatistics(id) {
+ return request({
+ url: `/room/project/${id}/statistics`,
+ method: 'get'
+ })
+}
+
+// 获取所有项目统计数据(整体概况)
+export function getAllProjectStatistics() {
+ return request({
+ url: '/room/project/statistics',
+ method: 'get'
+ })
+}
+
+// 获取标签列表
+export function getTagByType(data) {
+ return request({
+ url: '/admin/tag/getTagsByType',
+ method: 'post',
+ data: data
+ })
+}
\ No newline at end of file
diff --git a/pc/src/api/resource.js b/pc/src/api/resource.js
new file mode 100644
index 0000000..12fb916
--- /dev/null
+++ b/pc/src/api/resource.js
@@ -0,0 +1,54 @@
+import request from '@/utils/request'
+
+/**
+ * 上传附件
+ * @param {File} file 文件对象
+ * @returns {Promise} 返回包含fileId和fileName的Promise
+ */
+export function uploadAttachment(file) {
+ const formData = new FormData()
+ formData.append('file', file)
+ return request({
+ url: '/resource/attachment/uploadAttachment',
+ method: 'post',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+/**
+ * 下载附件
+ * @param {string} fileId 文件ID
+ * @returns {Promise} 返回文件流的Promise
+ */
+export function downloadAttachment(fileId) {
+ return request({
+ url: `/resource/attachment/downloadAttachment?fileId=${fileId}`,
+ method: 'get',
+ responseType: 'blob'
+ })
+}
+
+/**
+ * 批量删除附件
+ * @param {Array} fileIds 文件ID数组
+ * @returns {Promise} 返回操作结果的Promise
+ */
+export function batchDeleteAttachment(fileIds) {
+ return request({
+ url: '/resource/attachment/batchDeleteAttachment',
+ method: 'post',
+ data: fileIds
+ })
+}
+
+/**
+ * 删除单个附件
+ * @param {string} fileId 文件ID
+ * @returns {Promise} 返回操作结果的Promise
+ */
+export function deleteAttachment(fileId) {
+ return batchDeleteAttachment([fileId])
+}
\ No newline at end of file
diff --git a/pc/src/api/room.js b/pc/src/api/room.js
new file mode 100644
index 0000000..79b20b2
--- /dev/null
+++ b/pc/src/api/room.js
@@ -0,0 +1,199 @@
+import request from '@/utils/request'
+
+// 查询房源列表
+export function listRoom(query) {
+ return request({
+ url: '/room/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询房源详细信息
+export function getRoom(id) {
+ return request({
+ url: '/room/' + id,
+ method: 'get'
+ })
+}
+
+// 新增房源
+export function addRoom(data) {
+ return request({
+ url: '/room/add',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改房源
+export function updateRoom(data) {
+ return request({
+ url: '/room/edit',
+ method: 'post',
+ data: data
+ })
+}
+
+// 删除房源
+export function delRoom(id) {
+ return request({
+ url: '/room/remove/' + id,
+ method: 'post'
+ })
+}
+
+// 批量删除房源
+export function delRoomBatch(ids) {
+ return request({
+ url: '/room/batch/remove/' + ids,
+ method: 'post'
+ })
+}
+
+// 导出房源
+export function exportRoom(query) {
+ return request({
+ url: '/room/template/export/batch',
+ method: 'post',
+ data: query,
+ responseType: 'blob'
+ })
+}
+
+// 下载导入模板
+export function downloadTemplate() {
+ return request({
+ url: '/room/template/download',
+ method: 'get',
+ responseType: 'blob'
+ })
+}
+
+// 导入房源数据
+export function importRoom(file) {
+ const formData = new FormData()
+ formData.append('file', file)
+ return request({
+ url: '/room/import',
+ method: 'post',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+// 查询房源标签列表
+export function listRoomTags() {
+ return request({
+ url: '/room/tags',
+ method: 'get'
+ })
+}
+
+// 获取项目列表
+export function listProjects() {
+ return request({
+ url: '/project/list',
+ method: 'get'
+ })
+}
+
+// 获取楼宇列表
+export function listBuildings(projectId) {
+ return request({
+ url: '/building/list',
+ method: 'get',
+ params: { projectId }
+ })
+}
+
+// 获取楼层列表
+export function listFloors(buildingId) {
+ return request({
+ url: '/building/floors',
+ method: 'get',
+ params: { buildingId }
+ })
+}
+
+// 远程调用 - 获取业户列表
+export function listOwners(query) {
+ return request({
+ url: '/customer/owners',
+ method: 'get',
+ params: query
+ })
+}
+
+// 远程调用 - 检查房源合同状态
+export function checkRoomContractStatus(roomId) {
+ return request({
+ url: '/contract/check/room/' + roomId,
+ method: 'get'
+ })
+}
+
+// 修改房源租赁状态
+export function updateRoomLeaseStatus(id, status) {
+ return request({
+ url: '/room/lease-status',
+ method: 'post',
+ data: { id, status }
+ })
+}
+
+// 检查房号是否存在
+export function checkRoomNumberExists(params) {
+ return request({
+ url: '/room/check-number',
+ method: 'get',
+ params: params
+ })
+}
+
+// 获取房源图片列表
+export function listRoomImages(params) {
+ return request({
+ url: '/room/images',
+ method: 'get',
+ params: params
+ })
+}
+
+// 上传房源图片
+export function uploadRoomImage(roomId, imageType, file, sortOrder) {
+ const formData = new FormData()
+ formData.append('roomId', roomId)
+ formData.append('imageType', imageType)
+ formData.append('file', file)
+ if (sortOrder !== undefined) {
+ formData.append('sortOrder', sortOrder)
+ }
+ return request({
+ url: '/room/upload',
+ method: 'post',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+// 删除房源图片
+export function deleteRoomImage(id) {
+ return request({
+ url: '/room/image/' + id,
+ method: 'post'
+ })
+}
+
+// 批量删除房源图片
+export function batchDeleteRoomImages(ids) {
+ return request({
+ url: '/room/images/batch',
+ method: 'post',
+ data: { ids }
+ })
+}
\ No newline at end of file
diff --git a/pc/src/assets/images/code.png b/pc/src/assets/images/code.png
new file mode 100644
index 0000000..67f1ea1
Binary files /dev/null and b/pc/src/assets/images/code.png differ
diff --git a/pc/src/assets/images/qrcode.svg b/pc/src/assets/images/qrcode.svg
new file mode 100644
index 0000000..9a30208
--- /dev/null
+++ b/pc/src/assets/images/qrcode.svg
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/assets/images/tag_01.png b/pc/src/assets/images/tag_01.png
new file mode 100644
index 0000000..feeeb61
Binary files /dev/null and b/pc/src/assets/images/tag_01.png differ
diff --git a/pc/src/assets/images/tag_02.png b/pc/src/assets/images/tag_02.png
new file mode 100644
index 0000000..01b6dff
Binary files /dev/null and b/pc/src/assets/images/tag_02.png differ
diff --git a/pc/src/assets/images/tag_03.png b/pc/src/assets/images/tag_03.png
new file mode 100644
index 0000000..53c3ccf
Binary files /dev/null and b/pc/src/assets/images/tag_03.png differ
diff --git a/pc/src/assets/images/tag_04.png b/pc/src/assets/images/tag_04.png
new file mode 100644
index 0000000..2d275c2
Binary files /dev/null and b/pc/src/assets/images/tag_04.png differ
diff --git a/pc/src/assets/styles/index.scss b/pc/src/assets/styles/index.scss
new file mode 100644
index 0000000..2856549
--- /dev/null
+++ b/pc/src/assets/styles/index.scss
@@ -0,0 +1,24 @@
+html, body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ font-family: Avenir, Helvetica, Arial, sans-serif;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+.el-container {
+ height: 100%;
+}
+
+.el-header {
+ padding: 0;
+ height: 60px;
+}
+
+.el-main {
+ background-color: #f0f2f5;
+ padding: 20px;
+}
\ 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/components/RegionSelector.vue b/pc/src/components/RegionSelector.vue
new file mode 100644
index 0000000..2713270
--- /dev/null
+++ b/pc/src/components/RegionSelector.vue
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/layout/index.vue b/pc/src/layout/index.vue
new file mode 100644
index 0000000..18de30d
--- /dev/null
+++ b/pc/src/layout/index.vue
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/main.js b/pc/src/main.js
new file mode 100644
index 0000000..58a436d
--- /dev/null
+++ b/pc/src/main.js
@@ -0,0 +1,50 @@
+import Vue from 'vue'
+import App from './App.vue'
+import router from './router'
+import store from './store'
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+import './assets/styles/index.scss'
+
+Vue.use(ElementUI)
+Vue.config.productionTip = false
+
+// 添加下载方法
+Vue.prototype.download = function(res, fileName) {
+ // 检查响应类型
+ if (res.type && (res.type === 'application/vnd.ms-excel' ||
+ res.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
+ res.type.includes('excel') ||
+ res.type === 'application/octet-stream')) {
+ // 如果已经是Blob类型且是Excel类型,直接使用
+ const blob = res
+ const link = document.createElement('a')
+ link.href = URL.createObjectURL(blob)
+ link.download = fileName
+ link.click()
+ URL.revokeObjectURL(link.href)
+ } else {
+ // 如果不是Blob类型或无法确定类型,根据文件扩展名处理
+ let blob
+ if (fileName.endsWith('.xlsx') || fileName.endsWith('.xls')) {
+ // Excel文件需要使用二进制格式
+ blob = new Blob([res], {
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+ })
+ } else {
+ // 其他类型使用默认处理
+ blob = new Blob([res])
+ }
+ const link = document.createElement('a')
+ link.href = URL.createObjectURL(blob)
+ link.download = fileName
+ link.click()
+ URL.revokeObjectURL(link.href)
+ }
+}
+
+new Vue({
+ router,
+ store,
+ render: h => h(App)
+}).$mount('#app')
\ No newline at end of file
diff --git a/pc/src/router/index.js b/pc/src/router/index.js
new file mode 100644
index 0000000..58d4b6c
--- /dev/null
+++ b/pc/src/router/index.js
@@ -0,0 +1,75 @@
+import Vue from 'vue'
+import VueRouter from 'vue-router'
+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)
+
+const routes = [
+ {
+ path: '/',
+ component: () => import('@/layout/index'),
+ redirect: '/home',
+ hidden: true
+ },
+ {
+ path: '/home',
+ component: () => import('@/layout/index'),
+ children: [
+ {
+ path: '',
+ name: 'Home',
+ component: () => import('../views/Home.vue'),
+ meta: { title: '首页', icon: 'el-icon-s-home' }
+ }
+ ],
+ meta: { title: '首页', icon: 'el-icon-s-home' }
+ },
+ systemRoutes,
+ projectRoutes,
+ financeRoutes,
+ merchantRoutes,
+ {
+ path: '/asset',
+ component: Layout,
+ name: 'Asset',
+ meta: { title: '资产管理', icon: 'el-icon-s-management' },
+ children: [
+ {
+ path: 'location',
+ component: () => import('@/views/asset/location/index'),
+ name: 'AssetLocation',
+ meta: { title: '资产位置设置', icon: 'el-icon-location' }
+ },
+ {
+ path: 'classification',
+ component: () => import('@/views/asset/classification/index'),
+ name: 'AssetClassification',
+ meta: { title: '资产分类设置', icon: 'el-icon-folder' }
+ },
+ {
+ path: 'inventory',
+ component: () => import('@/views/asset/inventory/index'),
+ name: 'AssetInventory',
+ meta: { title: '资产清单管理', icon: 'el-icon-files' }
+ },
+ {
+ path: 'labelPage',
+ component: () => import('@/views/asset/labelPage/index'),
+ name: 'AssetLabel',
+ meta: { title: '资产标签设置', icon: 'el-icon-printer' }
+ }
+ ]
+ }
+]
+
+const router = new VueRouter({
+ mode: 'history',
+ base: process.env.BASE_URL,
+ routes
+})
+
+export default router
\ No newline at end of file
diff --git a/pc/src/router/modules/finance.js b/pc/src/router/modules/finance.js
new file mode 100644
index 0000000..fc11235
--- /dev/null
+++ b/pc/src/router/modules/finance.js
@@ -0,0 +1,54 @@
+import Layout from '@/layout/index'
+
+export default {
+ path: '/finance',
+ component: Layout,
+ name: 'Finance',
+ meta: { title: '业务财务', icon: 'el-icon-money' },
+ redirect: '/finance/feeType',
+ children: [
+ {
+ path: 'feeType',
+ 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' }
+ },
+ {
+ path: 'chargeStandard',
+ component: () => import('@/views/finance/chargeStandard/index.vue'),
+ name: 'ChargeStandard',
+ meta: { title: '收费标准', icon: 'el-icon-price-tag' }
+ },
+ {
+ path: 'billList',
+ component: () => import('@/views/finance/billList/index.vue'),
+ name: 'BillList',
+ meta: { title: '所有账单', icon: 'el-icon-notebook-2' }
+ },
+ {
+ path: 'transaction',
+ component: () => import('@/views/finance/transaction/index.vue'),
+ name: 'Transaction',
+ meta: { title: '收支流水', icon: 'el-icon-money' }
+ },
+ {
+ path: 'receiptRecord',
+ component: () => import('@/views/finance/receiptRecord/index.vue'),
+ name: 'ReceiptRecord',
+ meta: { title: '收据记录', icon: 'el-icon-document-copy' }
+ },
+ {
+ path: 'receipt/issue/:billId',
+ component: () => import('@/views/finance/receipt/issue.vue'),
+ name: 'IssueReceipt',
+ meta: { title: '开具收据', activeMenu: '/finance/billList' },
+ hidden: true
+ }
+ ]
+}
\ 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/router/modules/project.js b/pc/src/router/modules/project.js
new file mode 100644
index 0000000..ef3de56
--- /dev/null
+++ b/pc/src/router/modules/project.js
@@ -0,0 +1,27 @@
+export default {
+ path: '/project',
+ component: () => import('@/layout/index'),
+ redirect: '/project/list',
+ name: 'Project',
+ meta: { title: '项目管理', icon: 'el-icon-office-building' },
+ children: [
+ {
+ path: 'list',
+ name: 'ProjectList',
+ component: () => import('@/views/project/index'),
+ meta: { title: '项目列表' }
+ },
+ {
+ path: 'building',
+ name: 'BuildingList',
+ component: () => import('@/views/project/building/index'),
+ meta: { title: '楼宇列表' }
+ },
+ {
+ path: 'room',
+ name: 'RoomList',
+ component: () => import('@/views/project/room/index'),
+ meta: { title: '房源列表' }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/pc/src/router/modules/system.js b/pc/src/router/modules/system.js
new file mode 100644
index 0000000..d610e93
--- /dev/null
+++ b/pc/src/router/modules/system.js
@@ -0,0 +1,15 @@
+export default {
+ path: '/system',
+ component: () => import('@/layout/index'),
+ redirect: '/system/department-member',
+ name: 'System',
+ meta: { title: '系统管理', icon: 'el-icon-s-tools' },
+ children: [
+ {
+ path: 'department-member',
+ component: () => import('@/views/system/department-member/index'),
+ name: 'DepartmentMember',
+ meta: { title: '部门成员管理', icon: 'el-icon-office-building' }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/pc/src/store/index.js b/pc/src/store/index.js
new file mode 100644
index 0000000..3a7f2d7
--- /dev/null
+++ b/pc/src/store/index.js
@@ -0,0 +1,15 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+
+export default new Vuex.Store({
+ state: {
+ },
+ mutations: {
+ },
+ actions: {
+ },
+ modules: {
+ }
+})
\ No newline at end of file
diff --git a/pc/src/utils/auth.js b/pc/src/utils/auth.js
new file mode 100644
index 0000000..92f056a
--- /dev/null
+++ b/pc/src/utils/auth.js
@@ -0,0 +1,56 @@
+/**
+ * 用户鉴权相关工具方法
+ */
+
+/**
+ * 获取当前登录用户ID
+ * @returns {string} 用户ID
+ */
+export function getUserId() {
+ // 从本地存储中获取用户信息
+ const userInfo = localStorage.getItem('userInfo')
+ if (userInfo) {
+ try {
+ const user = JSON.parse(userInfo)
+ return user.id || user.userId || ''
+ } catch (e) {
+ console.error('解析用户信息失败', e)
+ return ''
+ }
+ }
+ return ''
+}
+
+/**
+ * 获取用户信息
+ * @returns {Object} 用户信息对象
+ */
+export function getUserInfo() {
+ const userInfo = localStorage.getItem('userInfo')
+ if (userInfo) {
+ try {
+ return JSON.parse(userInfo)
+ } catch (e) {
+ console.error('解析用户信息失败', e)
+ return {}
+ }
+ }
+ return {}
+}
+
+/**
+ * 保存用户信息到本地存储
+ * @param {Object} userInfo 用户信息对象
+ */
+export function setUserInfo(userInfo) {
+ if (userInfo) {
+ localStorage.setItem('userInfo', JSON.stringify(userInfo))
+ }
+}
+
+/**
+ * 清除用户信息
+ */
+export function clearUserInfo() {
+ localStorage.removeItem('userInfo')
+}
\ 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
new file mode 100644
index 0000000..1efad82
--- /dev/null
+++ b/pc/src/utils/request.js
@@ -0,0 +1,57 @@
+import axios from 'axios'
+import { Message } from 'element-ui'
+import { API_SUCCESS_CODE } from './constants'
+
+// 创建axios实例
+const service = axios.create({
+ baseURL: '/', // 修改为相对路径,使用代理
+ // baseURL: process.env.VUE_APP_BASE_API, // 使用环境变量中的接口地址
+
+ timeout: 10000 // 请求超时时间
+})
+
+// 请求拦截器
+service.interceptors.request.use(
+ config => {
+ // 可以在这里添加请求头等信息
+ return config
+ },
+ error => {
+ console.log(error)
+ return Promise.reject(error)
+ }
+)
+
+// 响应拦截器
+service.interceptors.response.use(
+ response => {
+ // 如果是blob类型(文件下载),直接返回blob数据
+ if (response.config.responseType === 'blob') {
+ return response.data
+ }
+
+ const res = response.data
+ // 如果返回的状态码不是成功码,则判断为错误
+ if (res.code !== API_SUCCESS_CODE) {
+ Message({
+ message: res.msg || res.message || '系统错误',
+ type: 'error',
+ duration: 5 * 1000
+ })
+ return Promise.reject(new Error(res.msg || res.message || '系统错误'))
+ } else {
+ return res
+ }
+ },
+ error => {
+ console.log('err' + error)
+ Message({
+ message: error.message,
+ type: 'error',
+ duration: 5 * 1000
+ })
+ return Promise.reject(error)
+ }
+)
+
+export default service
\ No newline at end of file
diff --git a/pc/src/views/Home.vue b/pc/src/views/Home.vue
new file mode 100644
index 0000000..d53bc9c
--- /dev/null
+++ b/pc/src/views/Home.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+
+
+ 10
+
+
+
+
+
+
+
+ 95
+
+
+
+
+
+
+
+ 5
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/asset/classification/index.vue b/pc/src/views/asset/classification/index.vue
new file mode 100644
index 0000000..aea1b3e
--- /dev/null
+++ b/pc/src/views/asset/classification/index.vue
@@ -0,0 +1,772 @@
+
+
+
+
+
+
+
+
+
+
+ {{ node.label }}
+
+ ({{ data.children.length }})
+
+
+
+
+
+
+
+
+
+
+ 分类列表
+ 新增分类
+ 批量删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+ {{ getParentName(scope.row.parentId) }}
+
+
+
+
+
+ {{ scope.row.status === '1' ? '启用' : '禁用' }}
+
+
+
+
+
+
+ 修改
+
+ {{ scope.row.status === '1' ? '禁用' : '启用' }}
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 启用
+ 禁用
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/asset/inventory/components/AssetDetail.vue b/pc/src/views/asset/inventory/components/AssetDetail.vue
new file mode 100644
index 0000000..eaaa81a
--- /dev/null
+++ b/pc/src/views/asset/inventory/components/AssetDetail.vue
@@ -0,0 +1,273 @@
+
+
+
+
+
+ {{ assetDetail.assetCode || assetDetail.code }}
+ {{ getClassificationName(assetDetail.classificationId) }}
+ {{ assetDetail.assetName || assetDetail.name }}
+
+ {{ getStatusText(assetDetail.assetStatus || assetDetail.status) }}
+
+ {{ assetDetail.brand }}
+ {{ assetDetail.model }}
+ {{ assetDetail.serialNumber }}
+ {{ assetDetail.administratorName }}
+ {{ assetDetail.companyName }}
+ {{ getLocationName(assetDetail.locationId) }}
+
+ {{ assetDetail.purchaseType === '1' ? '采购' : assetDetail.purchaseType === '2' ? '租赁' : '-' }}
+
+ {{ assetDetail.purchaseAmount }}
+ {{ assetDetail.purchaseDate || assetDetail.purchaseTime }}
+ {{ assetDetail.storageDate || assetDetail.storageTime }}
+ {{ assetDetail.expectedUsePeriod || assetDetail.expectedDepreciationPeriod }}
+ {{ assetDetail.expectedDepreciationPeriod }}
+ {{ assetDetail.maintenanceDueDate || assetDetail.maintenanceTime }}
+ {{ assetDetail.maintenanceDescription }}
+ {{ assetDetail.remark }}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/asset/inventory/components/AssetForm.vue b/pc/src/views/asset/inventory/components/AssetForm.vue
new file mode 100644
index 0000000..88e0912
--- /dev/null
+++ b/pc/src/views/asset/inventory/components/AssetForm.vue
@@ -0,0 +1,593 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/asset/inventory/components/AssetLabelPrint.vue b/pc/src/views/asset/inventory/components/AssetLabelPrint.vue
new file mode 100644
index 0000000..bf0c003
--- /dev/null
+++ b/pc/src/views/asset/inventory/components/AssetLabelPrint.vue
@@ -0,0 +1,528 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ field.label }}: {{ asset[field.key] }}
+
+
+
+
+
+
+
+
+
+ 打印
+ 取消
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/asset/inventory/components/AssetLabelPrint.zip b/pc/src/views/asset/inventory/components/AssetLabelPrint.zip
new file mode 100644
index 0000000..db49963
Binary files /dev/null and b/pc/src/views/asset/inventory/components/AssetLabelPrint.zip differ
diff --git a/pc/src/views/asset/inventory/index.vue b/pc/src/views/asset/inventory/index.vue
new file mode 100644
index 0000000..5f7795d
--- /dev/null
+++ b/pc/src/views/asset/inventory/index.vue
@@ -0,0 +1,851 @@
+
+
+
+
+ 资产清单
+
+ 新增资产
+ 批量导入
+ 导出
+ 打印标签
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+ 全部
+
+ {{ item.label }}
+
+ 列显示
+
+
+
+
+
+
+
+
+
+ {{ scope.row.assetCode }}
+
+
+
+
+ {{ getClassificationName(scope.row.classificationId) }}
+
+
+
+
+
+ {{ scope.row.assetStatus }}
+
+
+
+
+
+
+
+
+
+ {{ getLocationName(scope.row.locationId) }}
+
+
+
+
+
+ {{ scope.row.purchaseType === '1' ? '采购' : '租赁' }}
+
+
+
+
+
+
+
+
+
+
+ 无
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 将文件拖到此处,或点击上传
+
+
下载模板
+
只允许导入xls、xlsx格式文件。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/asset/labelPage/index.vue b/pc/src/views/asset/labelPage/index.vue
new file mode 100644
index 0000000..0f63e8a
--- /dev/null
+++ b/pc/src/views/asset/labelPage/index.vue
@@ -0,0 +1,623 @@
+
+
+
+
+ 资产标签设置
+
+
+
+
+
+
选择模板
+
+
+
+
+
+
+
+
模板{{ index + 1 }}
+
{{ getTemplateLimitText(index) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ field.name }}{{ index === 1 ? field.name.length > 2 ? '' : ' ' : ''
+ }}:
+ {{ field.value || 'XXXXXXXXXX' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
编辑标签
+
+
+
+
+ 当前模板最多支持{{ getMaxFieldsCount() }}个字段
+
+
+
+
+ {{ field.name }}
+
+
+
+
+
+
+
+
+ 保存
+ 重置
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/asset/location/index.vue b/pc/src/views/asset/location/index.vue
new file mode 100644
index 0000000..eb36953
--- /dev/null
+++ b/pc/src/views/asset/location/index.vue
@@ -0,0 +1,785 @@
+
+
+
+
+
+
+
+
+
+
+ {{ node.label }}
+
+ ({{ data.children.length }})
+
+
+
+
+
+
+
+
+
+
+ 位置列表
+ 新增位置
+ 批量删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+ {{ getParentName(scope.row.parentId) }}
+
+
+
+
+
+
+ {{ scope.row.status === '1' ? '启用' : '禁用' }}
+
+
+
+
+
+
+ 修改
+
+ {{ scope.row.status === '1' ? '禁用' : '启用' }}
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 启用
+ 禁用
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/billList/components/AddBill.vue b/pc/src/views/finance/billList/components/AddBill.vue
new file mode 100644
index 0000000..6ed1402
--- /dev/null
+++ b/pc/src/views/finance/billList/components/AddBill.vue
@@ -0,0 +1,977 @@
+
+
+
+
+
+
+
+ 含税
+ 不含税
+
+
+
+
+
+
+
+ 正常
+ 罚金
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加附件
+ 只能上传jpg/png/pdf文件,且不超过5MB
+
+
+
+
+
+
+
+
+ 预览
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
预览加载失败,请尝试下载后查看
+
+ 下载文件
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/billList/components/BillDetail.vue b/pc/src/views/finance/billList/components/BillDetail.vue
new file mode 100644
index 0000000..12b06dc
--- /dev/null
+++ b/pc/src/views/finance/billList/components/BillDetail.vue
@@ -0,0 +1,2720 @@
+
+
+
+
+
+
+ {{ billDetail.totBillNo }}
+ {{ getBillSourceName(billDetail.billSource) }}
+
+
+ {{ billDetail.billStatus === '1' ? '开启' : '关闭' }}
+
+
+ {{ billDetail.paysdName }}
+ {{ billDetail.payeeContact }}
+ {{ billDetail.contractNumber || '无' }}
+ {{ billDetail.feTpName }}
+
+ {{ billDetail.chggBgnDt }} 至 {{ billDetail.chggEndDt }}
+
+ {{ billDetail.pybDt }}
+
+
+ {{ getClearStatusName(billDetail.clearStatus) }}
+
+
+
+
+ {{ billDetail.overdueStatus === '1' ? '逾期' : '正常' }}
+
+
+
+
+ {{ getLateFeeStatusName(billDetail.ovdueStatus) }}
+
+
+ {{ formatAmount(billDetail.accblAmt) }}
+ {{ formatAmount(billDetail.accigRcvAmt) }}
+ {{ formatAmount(billDetail.atmRecvAmt) }}
+ {{ formatAmount(billDetail.needAmount) }}
+ {{ formatAmount(billDetail.adjAmt) }}
+ {{ formatAmount(billDetail.receivableOvdueAmt) }}
+ {{ billDetail.taxRate }}%
+ {{ formatAmount(billDetail.paybleTaxAmount) }}
+ {{ billDetail.taxInclusiveRule == '1'?'含税':billDetail.taxInclusiveRule == '2'?'不含税':'' }}
+ {{ billDetail.specialBillType == '1'? '正常' : billDetail.specialBillType == '2'? '罚金':''}}
+
+
+ {{ billDetail.receiptStatus === '1' ? '已开据' : '未开据' }}
+
+
+ {{ billDetail.corNm }}
+ {{ billDetail.rentArea }} ㎡
+ {{ billDetail.projectName }}
+ {{ billDetail.billRemark || '无' }}
+
+
+
+
+
+
+
+
+ {{ formatAmount(scope.row.receivableAmount) }}
+
+
+
+
+ {{ scope.row.taxRate }}%
+
+
+
+
+ {{ formatAmount(scope.row.taxAmount) }}
+
+
+
+
+
+
+
+
+ 调整
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.adjTpCd === '1' ? '调增' : '调减' }}
+
+
+
+
+
+ {{ scope.row.adjMethod === '1' ? '按金额调整' : '按比例调整' }}
+
+
+
+
+ {{ formatAmount(scope.row.adjAmt) }}
+
+
+
+
+ {{ scope.row.adjRate ? scope.row.adjRate + '%' : '-' }}
+
+
+
+
+
+ {{ scope.row.adjStatus === '1' ? '正常' : '作废' }}
+
+
+
+
+
+ {{ scope.row.billDetailType === '1' ? '原账单' : '滞纳金'}}
+
+
+
+
+ {{ scope.row.adjSource === '1' ? '账单直接调整' : '合同调整' }}
+
+
+
+
+
+
+ 附件详情
+ 作废
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.dcFlagCode === '1' ? '贷(收入)' : '借(支出)' }}
+
+
+
+
+
+
+
+
+ {{ formatAmount(scope.row.occuAmt) }}
+
+
+
+
+ {{ formatAmount(scope.row.refundAmt) }}
+
+
+
+
+ {{ getPayChannelName(scope.row.payChannel) }}
+
+
+
+
+ {{ scope.row.billDetailType === '1' ? '原账单' : '滞纳金' }}
+
+
+
+
+
+ 附件详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ formatAmount(scope.row.receiptAmount) }}
+
+
+
+
+
+ {{ scope.row.receiptStatusDesc }}
+
+
+
+
+
+
+
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 预览
+ 下载
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
预览加载失败,请尝试下载后查看
+
+ 下载文件
+
+
+
+
+
+
+
+
+
+
+
+ 调增
+ 调减
+
+
+
+
+
+
+
+
+
+
+ 按金额调整
+ 按比例调整
+
+
+
+
+
+
+ 调整后金额: {{ formatAmount(adjustedAmount) }}
+
+
+
+
+
+ 调整后金额: {{ formatAmount(adjustedAmount) }}
+
+
+
+
+
+
+
+
+
+ 添加附件
+ 只能上传jpg/png/pdf文件,且不超过5MB
+
+
+
+
+
+
+ 预览
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 预览
+ 下载
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
账单状态
+
+
+
+ {{ getClearStatusName(billDetail.clearStatus) }}
+
+
+
+
+
+
+
+
费用信息
+
+ {{ billDetail.feTpName }}
+ {{ formatAmount(billDetail.accigRcvAmt) }}
+ {{ formatAmount(billDetail.atmRecvAmt) }}
+ {{ formatAmount(billDetail.needAmount) }}
+
+
+
+
+
+
+ 收完
+
+
+
+
+ {{ formatAmount(remainingAmount) }}
+
+
+
+
+
+
+
+
+
+
+
支付方式
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
附件信息
+
+
+ 添加附件
+ 只能上传jpg/png/pdf文件,且不超过5MB
+
+
+
+
+
+
+
+ 预览
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加附件
+ 只能上传jpg/png/pdf文件,且不超过5MB
+
+
+
+
+
+
+ 预览
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 预览
+ 下载
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+ 点击上传
+ 只能上传jpg/png/pdf文件,且不超过5MB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
收据信息
+
+ {{ receiptDetail.receiptNo || '-' }}
+ {{ receiptDetail.ruleName || '-' }}
+ {{ receiptDetail.receiptDate || '-' }}
+ {{ receiptDetail.paymentMethodsDesc || '-' }}
+ {{ receiptDetail.feeType || '-' }}
+ {{ receiptDetail.feeName || '-' }}
+ {{ formatAmount(receiptDetail.receiptAmount) }}
+
+
+ {{ receiptDetail.receiptStatusDesc || '-' }}
+
+
+
+
+
+ 交款方信息
+
+ {{ receiptDetail.payerUnit || '-' }}
+ {{ receiptDetail.payerName || '-' }}
+ {{ receiptDetail.payerAddress || '-' }}
+ {{ receiptDetail.payerPhone || '-' }}
+
+
+
+ 收款方信息
+
+ {{ receiptDetail.payeeUnitName || '-' }}
+ {{ receiptDetail.payeeName || '-' }}
+ {{ receiptDetail.payeeAddress || '-' }}
+ {{ receiptDetail.payeePhone || '-' }}
+
+
+
+ 备注信息
+
+ {{ receiptDetail.remark || '-' }}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/billList/index.vue b/pc/src/views/finance/billList/index.vue
new file mode 100644
index 0000000..9750392
--- /dev/null
+++ b/pc/src/views/finance/billList/index.vue
@@ -0,0 +1,463 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 添加收款账单
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ getClearStatusName(scope.row.clearStatus) }}
+
+
+
+
+
+
+ {{ scope.row.accblAmt ? scope.row.accblAmt.toFixed(2) : '0.00' }}
+
+
+
+
+ {{ scope.row.accigRcvAmt ? scope.row.accigRcvAmt.toFixed(2) : '0.00' }}
+
+
+
+
+ {{ scope.row.atmRecvAmt ? scope.row.atmRecvAmt.toFixed(2) : '0.00' }}
+
+
+
+
+
+
+
+
+ 查看
+
+
+ 开具收据
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/chargeStandard/index.vue b/pc/src/views/finance/chargeStandard/index.vue
new file mode 100644
index 0000000..f882082
--- /dev/null
+++ b/pc/src/views/finance/chargeStandard/index.vue
@@ -0,0 +1,2672 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+ 新增
+
+
+
+
+
+
+
+ {{ scope.row.standardName }}
+
+
+
+
+ {{ scope.row.chargeMode === '1' ? '周期性费用' : '一次性费用' }}
+
+
+
+
+
+ {{ formatPriceUnit(scope.row.priceU, scope.row.chargeMode) }}
+
+
+
+
+
+
+ {{ getStatusName(scope.row.status) }}
+
+
+
+
+
+
+ {{ scope.row.bindingObjectType === '1' ? '房间' : '车位' }}
+
+
+
+
+ 绑定数据源+生成账单
+
+
+
+
+ 立即失效
+ 删除
+
+
+
+
+
+
+
+
+
+
+ {{ detailForm.standardName }}
+
+ {{ detailForm.bindingObjectType === '1' ? '房间' : '车位' }}
+
+ {{ detailForm.projectName }}
+ {{ detailForm.companyName }}
+ {{ detailForm.accountName }}
+ {{ detailForm.bankName }}
+ {{ detailForm.bankAccountNumber }}
+
+ {{ detailForm.chargeMode === '1' ? '周期性费用' : '一次性费用' }}
+
+ {{ detailForm.feTpName }}
+ {{ detailForm.effectiveDate }}
+ {{ detailForm.expiryDate }}
+ {{ detailForm.price }}
+
+ {{ formatPriceUnit(detailForm.priceU, detailForm.chargeMode) }}
+
+
+ {{ detailForm.taxInclusiveRule === '1' ? '含税' : '不含税' }}
+
+
+ {{ detailForm.dayPriceConversionRule === '1' ? '按自然月换算' : '按年换算' }}
+
+ {{ detailForm.decimalPrecisionPrice }}
+
+ {{ detailForm.receivableAmountPrecision }}
+
+
+
+ {{ formatPaymentTimeRule(detailForm) }}
+
+
+ {{ detailForm.billingType === '1' ? '按月计费' : '按实际天数计费' }}
+
+
+ {{ detailForm.chrgingUnitVal }}
+
+
+ {{ detailForm.remitCycleVal }}个月一付
+
+
+ {{ formatBillDivisionMethod(detailForm.billDivisionMethod) }}
+
+
+
+ {{ detailForm.ovdueStartDays }}
+
+
+ {{ formatPercentage(detailForm.ovdueIntRate) }}
+
+
+ {{ formatPercentage(detailForm.ovdueLimitRate) }}
+
+
+ {{ getStatusName(detailForm.status) }}
+
+ {{ detailForm.createTime }}
+
+
+
+
+
+
+
+ 收费设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.accountName }}
+ {{ item.companyName }}
+
+ {{ item.bankAccountNumber }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 基本信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 永久生效
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 付款信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 月一付
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 滞纳金设置
+
+
+
+
+
+
+
+
+
+ %
+
+
+
+
+
+ %
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 生成账单+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.billingType === '1' ? '按月计费' : '按实际天数计费' }}
+
+
+
+
+ {{ scope.row.price }} {{ formatPriceUnit(scope.row.priceU, '1') }}
+
+
+
+
+ {{ scope.row.remitCycleVal }}个月
+
+
+
+
+ {{ formatPaymentTimeRule(scope.row) }}
+
+
+
+
+
+ 查询绑定房间
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 收费标准信息
+
+
+ {{ billForm.standardName }}
+ {{ billForm.effectiveDate }}
+ {{ billForm.expiryDate }}
+
+ {{ getStatusName(billForm.status) }}
+
+
+ {{ billForm.bindingObjectType === '1' ? '房间' : '车位' }}
+
+ {{ billForm.projectName }}
+ {{ billForm.companyName }}
+ {{ billForm.accountName }}
+
+ {{ billForm.chargeMode === '1' ? '周期性费用' : '一次性费用' }}
+
+ {{ billForm.ovdueStartDays }}
+
+ {{ formatPercentage(billForm.ovdueIntRate) }}
+
+
+ {{ formatPercentage(billForm.ovdueLimitRate) }}
+
+
+
+
+
+
+
+ 生成账单基本信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 个月一付
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 绑定房源
+
+
+
+
+
+
+
+
+ 账单预览
+ 刷新预览
+
+
+
+
+
+ {{ scope.row.chggBgnDt }} 至 {{ scope.row.chggEndDt
+ }}
+
+
+
+
+
+
+
+ {{ scope.row.price }} {{ formatPriceUnit(scope.row.priceU, billForm.chargeMode) }}
+
+
+
+
+ {{ scope.row.room.roomNumber }}
+
+
+
+
+ {{ scope.row.room.rentalArea }}
+
+
+
+
+
+ {{ scope.row.accigRcvAmt.toFixed(2) }} 元
+
+
+
+
+
+ 账单总金额:
+ ¥ {{ previewBillTotal.toFixed(2) }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 房间名称: {{ bills[0].roomNumber }}
+ 楼层: {{ bills[0].floorName }}
+ 楼栋: {{ bills[0].buildingName }}
+
+
+
+
+
+
+ {{ formatDateTime(scope.row.chggBgnDt) }}
+
+
+
+
+ {{ formatDateTime(scope.row.chggEndDt) }}
+
+
+
+
+ {{ scope.row.accblAmt.toFixed(2) }} 元
+
+
+
+
+
+
+ {{ getClearStatusName(scope.row.clearStatus) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pc/src/views/finance/feeType/index.vue b/pc/src/views/finance/feeType/index.vue
new file mode 100644
index 0000000..9ae0efd
--- /dev/null
+++ b/pc/src/views/finance/feeType/index.vue
@@ -0,0 +1,655 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
+
+
+
+
+
+ {{ getCategoryNameById(scope.row.categoryId) }}
+
+
+
+
+
+ {{ scope.row.status === '1' ? '开启' : '关闭' }}
+
+
+
+
+
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是
+ 否
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 开启
+ 关闭
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/receipt/issue.vue b/pc/src/views/finance/receipt/issue.vue
new file mode 100644
index 0000000..bdd972a
--- /dev/null
+++ b/pc/src/views/finance/receipt/issue.vue
@@ -0,0 +1,563 @@
+
+
+
+
+ 开具收据
+ 返回
+
+
+
+
+
+
账单基本信息
+
+ {{ billInfo.totBillNo || '-' }}
+ {{ billInfo.paysdName || '-' }}
+ {{ billInfo.feTpName || '-' }}
+
+ {{ billInfo.chggBgnDt || '-' }} 至 {{ billInfo.chggEndDt || '-' }}
+
+ {{ formatAmount(billInfo.accigRcvAmt) }}
+ {{ formatAmount(billInfo.atmRecvAmt) }}
+
+
+
+
+
+
收据明细列表
+
+
+
+
+
+
+ -
+
+
+
+
+
+ {{ formatAmount(scope.row.availableAmount) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+
+
+
+
+
+
+
+
+ 已选择 {{ selectedItems.length }} 条明细,
+ 申请开据金额合计:{{ formatAmount(totalAmount) }}
+
+
+
+
+
+
+ 取消
+ 确认开具
+
+
+
+
+
+
+
+
+ 收据信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 交款方
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 收款方
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 备注
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/receiptRecord/components/ReceiptDetailDialog.vue b/pc/src/views/finance/receiptRecord/components/ReceiptDetailDialog.vue
new file mode 100644
index 0000000..27c48d8
--- /dev/null
+++ b/pc/src/views/finance/receiptRecord/components/ReceiptDetailDialog.vue
@@ -0,0 +1,829 @@
+
+
+
+
+
+
+
+
+ 收据编号:
+ {{ receiptInfo.receiptNumber }}
+
+
+
+
+ 开据日期:
+ {{ receiptInfo.receiptDate }}
+
+
+
+
+ 收据金额:
+ {{ formatMoney(receiptInfo.receiptAmount) }}
+
+
+
+
+ 支付方式:
+ {{ receiptInfo.payModeName }}
+
+
+
+
+ 开据人:
+ {{ receiptInfo.issuerName }}
+
+
+
+
+ 费用名称:
+ {{ receiptInfo.feeNm }}
+
+
+
+
+ 费用类型:
+ {{ receiptInfo.feeTpName }}
+
+
+
+
+ 收据模板:
+ {{ receiptInfo.receiptFileName }}
+
+
+
+
+ 状态:
+
+ {{ receiptInfo.receiptStatusName || getStatusText(receiptInfo.receiptStatus) }}
+
+
+
+
+
+ 收据文件:
+
+
+ {{ receiptInfo.receiptFileName }}
+
+
+ 下载
+ 打印
+ 在线预览
+
+
+
+
+
+
+
+
+
+
+
+ 交款单位:
+ {{ receiptInfo.paymUnitName }}
+
+
+
+
+ 交款人:
+ {{ receiptInfo.pymerName }}
+
+
+
+
+ 电话:
+ {{ receiptInfo.pymerPhone }}
+
+
+
+
+ 地址:
+ {{ receiptInfo.pymerAddr }}
+
+
+
+
+
+
+
+
+
+ 收款单位:
+ {{ receiptInfo.payeeUnitName }}
+
+
+
+
+ 收款人:
+ {{ receiptInfo.payeeName }}
+
+
+
+
+ 电话:
+ {{ receiptInfo.payeePhone }}
+
+
+
+
+ 地址:
+ {{ receiptInfo.payeeAddr }}
+
+
+
+
+
+
+
+
+
+
+ {{ formatMoney(row.amount) }}
+
+
+
+
+
+ 合计:
+ {{ formatMoney(receiptInfo.totalAmount) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ formatMoney(row.receivableAmount) }}
+
+
+
+
+ {{ formatMoney(row.receivedAmount) }}
+
+
+
+
+ {{ formatMoney(row.receiptAmount) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Office文档需要下载后查看,请点击下方按钮下载查看
+
+
+
+
+
+
+
+
预览加载失败,请尝试下载后查看
+
+ 下载文件
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/receiptRecord/index.vue b/pc/src/views/finance/receiptRecord/index.vue
new file mode 100644
index 0000000..8318aed
--- /dev/null
+++ b/pc/src/views/finance/receiptRecord/index.vue
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+ {{ row.receiptAmount ? '¥' + parseFloat(row.receiptAmount).toFixed(2) : '¥0.00' }}
+
+
+
+
+
+
+
+
+ {{ row.receiptStatusName || getStatusText(row.receiptStatus) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/receiptSetting/PayeeInfo.vue b/pc/src/views/finance/receiptSetting/PayeeInfo.vue
new file mode 100644
index 0000000..262cadc
--- /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..00fd6e4
--- /dev/null
+++ b/pc/src/views/finance/receiptSetting/ReceiptTemplate.vue
@@ -0,0 +1,943 @@
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增收据模版
+ 下载样例模板
+
+
+
+
+
+
+
+
+ {{ formatBuildingNames(scope.row.buildingIds) }}
+
+
+
+
+ 预览
+ 下载
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 点击上传
+ 仅支持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/finance/transaction/components/TransactionDetail.vue b/pc/src/views/finance/transaction/components/TransactionDetail.vue
new file mode 100644
index 0000000..ac342a0
--- /dev/null
+++ b/pc/src/views/finance/transaction/components/TransactionDetail.vue
@@ -0,0 +1,520 @@
+
+
+
+
+
+
+
+
+ 总体信息
+
+
+ {{ detailData.totalInfo && detailData.totalInfo.unitName || '-' }}
+
+ {{ formatAmount(detailData.totalInfo && detailData.totalInfo.totalAmount) }}
+
+
+ {{ formatAmount(detailData.totalInfo && detailData.totalInfo.matchedAmount) }}
+
+
+ {{ formatAmount(detailData.totalInfo && detailData.totalInfo.unmatchedAmount) }}
+
+
+
+
+
+
+
+
+
+ 流水信息
+
+
+
+
+ {{ (detailData.transaction && detailData.transaction.dcFlagCode === '0') ? '借(支出)' : '贷(收入)' }}
+
+
+
+ {{ formatAmount(detailData.transaction && detailData.transaction.occuAmt) }}
+
+ {{ detailData.transaction && detailData.transaction.inaccDate || '-' }}
+ {{ detailData.transaction && detailData.transaction.unitName || '-' }}
+ {{ getPaymentModeName(detailData.transaction && detailData.transaction.payModeName) }}
+ {{ detailData.transaction && detailData.transaction.opsAccname || '-' }}
+ {{ detailData.transaction && detailData.transaction.txVchrNo || '-' }}
+ {{ detailData.transaction && detailData.transaction.receiptNo || '-' }}
+ {{ detailData.transaction && detailData.transaction.conterName || '-' }}
+ {{ detailData.transaction && detailData.transaction.openaccBankName || '-' }}
+ {{ detailData.transaction && detailData.transaction.summ || '-' }}
+ {{ detailData.transaction && detailData.transaction.remark || '-' }}
+
+
+
+
+
+
+
+
+ 匹配账单
+
+
+
+
+
+
+ {{ scope.row.billingStartDate || '-' }} 至 {{ scope.row.billingEndDate || '-' }}
+
+
+
+
+ {{ formatAmount(scope.row.receivableAmount) }}
+
+
+
+
+ 暂无匹配账单
+
+
+
+
+
+
+
+
+ 附件信息
+
+ 添加附件
+
+
+
+
+
+
+
+
+ 预览
+ 下载
+ 删除
+
+
+
+
+ 暂无附件
+
+
+
+
+
+
+ 点击上传
+ 只能上传jpg/png/pdf文件,且不超过5MB
+
+
+
+
+
+
+
+
+
+ 操作记录
+
+
+
+
+
+
+
+ 暂无操作记录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
预览加载失败,请尝试下载后查看
+
+ 下载文件
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/finance/transaction/index.vue b/pc/src/views/finance/transaction/index.vue
new file mode 100644
index 0000000..7b19f8a
--- /dev/null
+++ b/pc/src/views/finance/transaction/index.vue
@@ -0,0 +1,352 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 搜索
+ 重置
+
+ 导出
+
+
+
+
+
+
+ {{ scope.row.projectName }} - {{ scope.row.buildingName }}
+
+
+
+
+
+
+
+
+
+ {{ scope.row.dcFlagCode === '0' ? '借(支出)' : '贷(收入)' }}
+
+
+
+
+
+ {{ scope.row.occuAmt ? parseFloat(scope.row.occuAmt).toFixed(2) : '0.00' }}
+
+
+
+
+ {{ getCurrencyName(scope.row.currCode) }}
+
+
+
+
+ {{ getPaymentModeName(scope.row.payModeName) }}
+
+
+
+
+
+
+ {{ getStatusName(scope.row.transactionStatus) }}
+
+
+
+
+
+
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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..a0c836d
--- /dev/null
+++ b/pc/src/views/merchant/clue-management/index.vue
@@ -0,0 +1,1759 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+ 新增线索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.statusName }}
+
+
+
+
+
+
+
+
+ {{ scope.row.projectName || getProjectNameById(scope.row.projectId) || '--' }}
+
+
+
+
+ {{ formatAreaRange(scope.row) }}
+
+
+
+
+
+
+ 跟进
+ 指定分配
+ 详情
+ 退回公海
+
+
+
+
+
+
+
+
+
+
+
+
+ 基础信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 需求信息
+
+
+
+
+
+ m²
+ -
+
+ m²
+
+
+
+
+
+
+ 元
+
+
+
+
+
+ 跟进人员
+
+
+
+
+ 指定人员
+ 加入公海
+ 分配给创建人
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 只能上传jpg/png文件,且不超过5MB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+ 暂无跟进记录
+
+
+
+
+
+ {{ getFollowStatusLabel(item.statusId) }}
+
+
{{ item.followContent }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentLead.createTime || '--' }}
+ {{ currentLead.projectName || getProjectNameById(currentLead.projectId) || '--' }}
+ {{ currentLead.buildingName || '--' }}
+ {{ currentLead.customerName || '--' }}
+ {{ currentLead.customerPhone || '--' }}
+ {{ currentLead.companyName || '--' }}
+ {{ formatAreaRange(currentLead) || '--' }}
+ {{ currentLead.remark || '--' }}
+
+
+
+
+ {{ currentLead.personnelName || '--' }}
+ {{ currentLead.teamName || '--' }}
+ {{ currentLead.assignmentTypeDesc || '--' }}
+ {{ currentLead.statusName || '--' }}
+ {{ currentLead.lastFollowTime || '--' }}
+ {{ currentLead.nextFollowTime || '--' }}
+
+
+
+
+ {{ currentLead.industry || '--' }}
+ {{ currentLead.age || '--' }}
+ {{ currentLead.budget || '--' }}
+ {{ currentLead.customerDetails || '--' }}
+ {{ currentLead.customerLevel || '--' }}
+ {{ currentLead.customerLevelDesc || '--' }}
+ {{ currentLead.leadSource || '--' }}
+ {{ currentLead.leadSourceDesc || '--' }}
+
+
+
+
+
+
+
+
+
+ {{ currentLead.customerName }} {{ currentLead.customerPhone }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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..1a91a81
--- /dev/null
+++ b/pc/src/views/merchant/intent-customer/index.vue
@@ -0,0 +1,1678 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+ 新增意向客户
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.isInitial ? '是' : '否' }}
+
+
+
+
+
+
+ {{ scope.row.isFinal ? '是' : '否' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.successRate }}%
+
+
+
+
+
+
+ {{ scope.row.statusName }}
+
+
+
+
+
+
+
+ {{ scope.row.budget ? `${scope.row.budget}元` : '--' }}
+
+
+
+
+ {{ getProjectNameById(scope.row.projectId) }}
+
+
+
+
+ {{ formatAreaRange(scope.row) }}
+
+
+
+
+
+
+ {{ tag.tagName }}
+
+ --
+
+
+
+
+ 跟进
+ 详情
+ 退回公海
+ 打标签
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.successRate }}%
+
+
+
+
+
+
+
+ {{ scope.row.budget ? `${scope.row.budget}元` : '--' }}
+
+
+
+
+ {{ getProjectNameById(scope.row.projectId) }}
+
+
+
+
+ {{ formatAreaRange(scope.row) }}
+
+
+
+
+
+
+ 指定分配
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+ 基础信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 需求信息
+
+
+
+
+
+ m²
+ -
+
+ m²
+
+
+
+
+
+
+
+
+ 元
+
+
+
+
+
+
+
+
+
+
+ 跟进人员
+
+
+
+
+ 指定人员
+ 加入公海
+ 分配给创建人
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.contractNo }}
+ {{ item.customerName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ m²
+ -
+
+ m²
+
+
+
+
+ 元
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
状态: {{ history.statusName }}
+
跟进人: {{ history.personnelName }} ({{
+ history.personnelPhone }})
+
内容: {{ history.followContent }}
+
+
+
+
合同编号: {{ history.contractNo }}
+
+
+
+ 暂无跟进历史
+
+
+
+
+
+
+
+
+
+
+ {{ currentCustomer.customerName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ customerDetail.createTime || '--' }}
+ {{ customerDetail.convertTime || '--' }}
+ {{ getProjectNameById(customerDetail.projectId) }}
+ {{ customerDetail.buildingName || '--' }}
+ {{ customerDetail.customerName || '--' }}
+ {{ customerDetail.customerPhone || '--' }}
+ {{ customerDetail.companyName || '--' }}
+ {{ customerDetail.industry || '--' }}
+ {{ customerDetail.expectSignDate || '--' }}
+ {{ formatAreaRange(customerDetail) || '--' }}
+ {{ customerDetail.budget ? `${customerDetail.budget}元` : '--'
+ }}
+ {{ customerDetail.successRate ? `${customerDetail.successRate}%` : '--'
+ }}
+
+
+ {{ tag.tagName }}
+
+
+ {{ customerDetail.remark || '--' }}
+
+
+
+
+ {{ customerDetail.personnelName || '--' }}
+ {{ customerDetail.managerName || '--' }}
+
+
+
+
+
+
+
+
+
+
+ 暂无合同信息
+
+
+
+
+
+
状态: {{ history.statusName }}
+
跟进人: {{ history.personnelName }} ({{
+ history.personnelPhone }})
+
内容: {{ history.followContent }}
+
+
+
+
合同编号: {{ history.contractNo }}
+
+
+
+ 暂无跟进历史
+
+
+
+
+
+
+
状态: {{ history.statusName }}
+
跟进人: {{ history.personnelName }} ({{
+ history.personnelPhone }})
+
内容: {{ history.followContent }}
+
+
+
+
+
+
+
+ 暂无线索跟进历史
+
+
+
+
+
+
+
+
+ {{ currentCustomer.customerName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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..0dd6442
--- /dev/null
+++ b/pc/src/views/merchant/merchant-personnel/index.vue
@@ -0,0 +1,1456 @@
+
+
+
+
+
+
+ 1. 招商团队可按照区域或其他方式进行分类,主要用作招商人员分组管理;
+ 2. 可以批量添加部门或个人为招商人员;若批量添加部门,则该部门下所有成员都会被设为招商人员;
+ 3. 等权限设置好,会自动按照上级管理流程。
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+ 新增招商人员
+
+
+
+
+
+
+ {{ scope.row.memberName }}
+ 招商经理
+
+
+
+
+
+
+
+
+
+ 移除人员
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+ 新增团队
+
+
+
+
+
+
+
+
+
+ {{ formatProjectNames(scope.row.projectIds) }}
+
+
+
+
+
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择
+
+ {{ teamForm.managerName }} ({{ teamForm.managerPhone }})
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加
+
+
+ {{ member.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
搜索结果
+
+
+ {{item.memberName}}
+ {{item.teamName}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 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..f190844
--- /dev/null
+++ b/pc/src/views/merchant/tag-management/index.vue
@@ -0,0 +1,776 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 按回车键可输入多个标签名称
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 按回车键可输入多个标签名称
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/project/building/index.vue b/pc/src/views/project/building/index.vue
new file mode 100644
index 0000000..56cf8c6
--- /dev/null
+++ b/pc/src/views/project/building/index.vue
@@ -0,0 +1,2007 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 楼宇列表
+ 新增楼宇
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+ 全部
+
+ 楼宇编号
+ 楼宇名称
+ 所属项目
+ 楼宇标签
+ 所属地区
+ 楼宇地址
+ 产权性质
+ 标准层高(m)
+ 建筑面积(m²)
+ 产权面积(m²)
+ 可租面积(m²)
+ 自用面积(m²)
+ 配套面积(m²)
+ 车位面积(m²)
+ 管理面积(m²)
+ 房间总数(间)
+ 出租率(%)
+ 在租面积(m²)
+ 在租合同数
+
+ 待租面积(m²)
+ 待租房间数
+
+ 列显示
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ getTagNameById(tagId) }}
+
+
+
+
+
+
+
+
+
+ {{ formatColumnValue(scope.row[col.prop], col.prop) }}
+
+
+
+
+
+
+ 编辑
+ 楼层管理
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 基础信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 楼宇面积
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 默认收支账户
+
+
+
+
+
+
+ {{ item.accountName }}
+ {{ item.companyName }}
+
+ {{ item.bankAccountNumber }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 基础信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 楼宇面积
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 默认收支账户
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 统计信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/project/index.vue b/pc/src/views/project/index.vue
new file mode 100644
index 0000000..408e560
--- /dev/null
+++ b/pc/src/views/project/index.vue
@@ -0,0 +1,594 @@
+
+
+
+
+
+
+ 项目列表
+ 新增项目
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 详情
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ detail.projectName }}
+ {{ detail.projectShortName }}
+ {{ detail.projectType }}
+ {{ detail.region }}
+ {{ detail.address }}
+ {{ detail.manageArea }}㎡
+ {{ detail.availableArea }}㎡
+ {{ detail.totalRooms }}
+ {{ detail.availableRooms }}
+
+
+ {{ tag.tagName }}
+
+ 暂无标签
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/project/room/components/DetailView.vue b/pc/src/views/project/room/components/DetailView.vue
new file mode 100644
index 0000000..c294a46
--- /dev/null
+++ b/pc/src/views/project/room/components/DetailView.vue
@@ -0,0 +1,353 @@
+
+
+
+
+
+ {{ roomDetail.projectName }}
+ {{ roomDetail.buildingName }}
+ {{ roomDetail.floorName }}
+ {{ roomDetail.roomNumber }}
+ {{ roomDetail.roomDigitalNumber }}
+ {{ roomDetail.roomManageNumber }}
+ {{ roomDetail.buildingArea }} m²
+ {{ roomDetail.rentalArea }} m²
+ {{ roomDetail.billingArea }} m²
+ {{ roomDetail.innerArea }} m²
+ {{ roomDetail.isVirtual === '1' ? '是' : '否' }}
+ {{ roomDetail.deliveryTime }}
+ {{ roomDetail.ownerName }}
+
+
+
+
+
+
+ {{ roomPropertyTypeText }}
+
+
+ {{ leaseStatusText }}
+
+ {{ roomStatusText }}
+ {{ roomTypeText }}
+ {{ roomDetail.roomRecordNumber }}
+ {{ roomDetail.height }} m
+ {{ roomDetail.loadValue }}
+ {{ decorationStatusText }}
+
+
+ {{ tag.tagName }}
+
+
+
+
+ {{ roomDetail.businessStatus === '1' ? '招商' : '不招商' }}
+
+
+ {{ roomDetail.availableDate }}
+
+ {{ roomDetail.price }} {{ priceUnitText }}
+
+
+ {{ roomDetail.floorPrice }} {{ floorPriceUnitText }}
+
+ {{ roomDetail.businessNumber }}
+ {{ roomDetail.businessCondition || '-' }}
+
+
+
+
+
房源图片
+
+
+
+
+
+
+
+
+
+
+ {{ roomDetail.usageRate || '-' }}
+ {{ roomDetail.officeLayout || '-' }}
+ {{ roomDetail.windowOrientation || '-' }}
+ {{ roomDetail.rentFreePeriod || '-' }}
+ {{ roomDetail.minLeaseTerm || '-' }}
+ {{ workstationCountRange }}
+
+
+
+
户型图
+
+
+
+
+
+
+
户型图说明
+
{{ roomDetail.floorPlanDesc }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/project/room/components/RoomForm.vue b/pc/src/views/project/room/components/RoomForm.vue
new file mode 100644
index 0000000..ed2bc10
--- /dev/null
+++ b/pc/src/views/project/room/components/RoomForm.vue
@@ -0,0 +1,1052 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/project/room/index.vue b/pc/src/views/project/room/index.vue
new file mode 100644
index 0000000..b551603
--- /dev/null
+++ b/pc/src/views/project/room/index.vue
@@ -0,0 +1,776 @@
+
+
+
+
+ 房源列表
+
+ 新增房源
+ 批量导入
+ 批量导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ {{ advanced ? '收起' : '展开' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.rentalStatus === '1' ? '待租' : scope.row.rentalStatus === '2' ? '已租' : '暂无' }}
+
+
+
+
+
+ {{ scope.row.decorationStatus === '1' ? '精装' :
+ scope.row.decorationStatus === '2' ? '简装' :
+ scope.row.decorationStatus === '3' ? '毛坯' :
+ scope.row.decorationStatus === '4' ? '标准交付' :
+ scope.row.decorationStatus === '5' ? '豪装' : '-' }}
+
+
+
+
+
+
+
+ {{ tag.tagName }}
+
+
+
+
+
+ {{ scope.row.isVirtual === '1' ? '是' : '否' }}
+
+
+
+
+
+ {{ scope.row.businessStatus === '1' ? '招商' : '不招商' }}
+
+
+
+
+
+
+ 详情
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+ 将文件拖到此处,或点击上传
+
+
下载模板
+
只允许导入xls、xlsx格式文件。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/system/department-member/index.vue b/pc/src/views/system/department-member/index.vue
new file mode 100644
index 0000000..9f843fb
--- /dev/null
+++ b/pc/src/views/system/department-member/index.vue
@@ -0,0 +1,946 @@
+
+
+
+
+
+
+
+ 部门管理
+ 新增部门
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 添加子部门
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ node.label }}
+ ({{ data.memberCount || 0 }})
+
+
+
+
+
+
+
+
+
+
+
+ 全部
+ 正常
+ 未激活
+
+
+
+
+
+
+
+
+
+ {{ scope.row.status === '1' ? '正常' : '禁用' }}
+
+
+
+
+
+
+
+
+
+ {{ scope.row.gender === '1' ? '男' : '女' }}
+
+
+
+
+
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 在职
+ 离职
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/system/department/index.vue b/pc/src/views/system/department/index.vue
new file mode 100644
index 0000000..c9d8699
--- /dev/null
+++ b/pc/src/views/system/department/index.vue
@@ -0,0 +1,203 @@
+
+
+
+
+ 部门管理
+ 新增部门
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/src/views/system/index.vue b/pc/src/views/system/index.vue
new file mode 100644
index 0000000..0519ecb
--- /dev/null
+++ b/pc/src/views/system/index.vue
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/pc/src/views/system/member/index.vue b/pc/src/views/system/member/index.vue
new file mode 100644
index 0000000..a9ded78
--- /dev/null
+++ b/pc/src/views/system/member/index.vue
@@ -0,0 +1,285 @@
+
+
+
+
+ 成员管理
+ 新增成员
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.status === '1' ? '在职' : '离职' }}
+
+
+
+
+
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 在职
+ 离职
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pc/vue.config.js b/pc/vue.config.js
new file mode 100644
index 0000000..63e0e94
--- /dev/null
+++ b/pc/vue.config.js
@@ -0,0 +1,24 @@
+module.exports = {
+ publicPath: '/',
+ outputDir: 'dist',
+ assetsDir: 'static',
+ productionSourceMap: false,
+ devServer: {
+ port: 8080,
+ open: true,
+ overlay: {
+ warnings: false,
+ errors: true
+ },
+ proxy: {
+ '/': {
+ target: 'http://192.168.137.3:8080/api/api',
+ // target: 'http://192.168.137.45:8080',
+ changeOrigin: true,
+ pathRewrite: {
+ '^/api': '/api'
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/园区前端.zip b/园区前端.zip
new file mode 100644
index 0000000..def265b
Binary files /dev/null and b/园区前端.zip differ
diff --git a/园区前端/h5.zip b/园区前端/h5.zip
new file mode 100644
index 0000000..4707fef
Binary files /dev/null and b/园区前端/h5.zip differ
diff --git a/园区前端/pc.zip b/园区前端/pc.zip
new file mode 100644
index 0000000..3e9b0d1
Binary files /dev/null and b/园区前端/pc.zip differ