first commit
155
README.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
|
||||||
|
|
||||||
|
使用 vue3 + javascript 开发项目
|
||||||
|
|
||||||
|
- ✅ Vue3
|
||||||
|
- ✅ JavaScript
|
||||||
|
- ✅ Pinia
|
||||||
|
- ✅ Pnpm
|
||||||
|
- ✅ Sass
|
||||||
|
|
||||||
|
## 工具库 utils
|
||||||
|
|
||||||
|
### 请求库
|
||||||
|
|
||||||
|
用作请求接口的,封装的 uni.request,返回一个 Promise。
|
||||||
|
|
||||||
|
**使用示例**
|
||||||
|
|
||||||
|
- request(options, [config])
|
||||||
|
|
||||||
|
**options参考**
|
||||||
|
|
||||||
|
| 名称 | 类型 | 必填 | 默认值 | 备注 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| url | `string` | 是 | - | 接口地址,示例:`/api/user/get` |
|
||||||
|
| method | `string` | 否 | GET | 可选项 `GET` `POST` `PUT` `DELETE` `OPTIONS` 等,参考 uni.request method 参数有效值 |
|
||||||
|
| data | `object` | 否 | - | 提交参数 |
|
||||||
|
| header | `object` | 否 | - | 请求头,示例 `{ token: '你的 token'}` |
|
||||||
|
|
||||||
|
**config参考**
|
||||||
|
|
||||||
|
| 名称 | 类型 | 必填 | 默认值 | 备注 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| baseUrl | `string` | 否 | - | 基础接口地址, 读取 .env 的 VITE_APP_BASE_URL |
|
||||||
|
| isReturnDefaultResponse | `bool` | 否 | false | 返回默认响应体,不做额外处理, 原样返回 |
|
||||||
|
| isTransformResponse | `bool` | 否 | true | 转换响应体,false 直接返回 data, true 自动处理业务代码报错提示等(前提 isReturnDefaultResponse 是 false) |
|
||||||
|
| ignoreCancel | `bool` | 否 | false | 忽略取消重复请求 |
|
||||||
|
| retryCount | `number` | 否 | 2 | 重试次数 |
|
||||||
|
| retryTimeout | `number` | 否 | 300 | 重试延迟 |
|
||||||
|
| withToken | `bool` | 否 | true | 携带 token |
|
||||||
|
| isAuth | `bool` | 否 | false | 接口是否鉴权,暂时无用,可在拦截器中扩展 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
🏷️ 所有接口请求都必须放在 `src/api/` 目录下统一维护
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// get 请求
|
||||||
|
export function getCaptchaImage() {
|
||||||
|
return request.get({
|
||||||
|
url: '/api/captchaImage',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// post 请求
|
||||||
|
export function login(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/user/login',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### @/utils/cache.js
|
||||||
|
|
||||||
|
缓存工具
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import cache from '@/utils/cache.js'
|
||||||
|
|
||||||
|
// 设置缓存
|
||||||
|
cache.set('token', '1b1b1b1b1b1')
|
||||||
|
|
||||||
|
// 获取缓存
|
||||||
|
cache.get('token')
|
||||||
|
// 1b1b1b1b1b1
|
||||||
|
|
||||||
|
// 删除缓存
|
||||||
|
cache.remove('token')
|
||||||
|
|
||||||
|
// 获取时间戳
|
||||||
|
cache.time()
|
||||||
|
// 1660060800
|
||||||
|
```
|
||||||
|
|
||||||
|
### @/utils/formatter.js
|
||||||
|
|
||||||
|
格式化工具
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { maskPhoneNumber, maskIdNumber} from '@/utils/formatter.js'
|
||||||
|
|
||||||
|
// 手机号加掩码
|
||||||
|
maskPhoneNumber('15112345678')
|
||||||
|
// 151****5678
|
||||||
|
|
||||||
|
// 证件号码加掩码
|
||||||
|
maskIdNumber('110101198506020011')
|
||||||
|
// 1101***********0011
|
||||||
|
```
|
||||||
|
|
||||||
|
### @/utils/message.js
|
||||||
|
|
||||||
|
操作反馈
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import {
|
||||||
|
showToast,
|
||||||
|
showAlert,
|
||||||
|
showLoading,
|
||||||
|
hideLoading,
|
||||||
|
useMessage
|
||||||
|
} from '@/utils/message.js'
|
||||||
|
|
||||||
|
// toast
|
||||||
|
showToast('操作成功')
|
||||||
|
|
||||||
|
// 模态确认框
|
||||||
|
showAlert('操作成功,请确认')
|
||||||
|
|
||||||
|
// 加载 loading
|
||||||
|
showLoading('拼命加载中')
|
||||||
|
hideLoading()
|
||||||
|
|
||||||
|
// 组合式api
|
||||||
|
const message = useMessage()
|
||||||
|
message.toast('提交成功')
|
||||||
|
message.success('操作成功')
|
||||||
|
message.error('操作失败')
|
||||||
|
message.alert('操作完成')
|
||||||
|
message.showLoading()
|
||||||
|
message.hideLoading()
|
||||||
|
```
|
||||||
|
|
||||||
|
### @/utils/validate.js
|
||||||
|
|
||||||
|
验证库
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import {
|
||||||
|
isUrl,
|
||||||
|
isPhoneNumber,
|
||||||
|
isIdCardValid,
|
||||||
|
isHttpProtocol,
|
||||||
|
isHttpsProtocol
|
||||||
|
} from '@/utils/validate.js'
|
||||||
|
|
||||||
|
isUrl('http://www.baidu.com') // true
|
||||||
|
isPhoneNumber('15112345601') // true
|
||||||
|
isIdCardValid('110101198506020011') // true
|
||||||
|
isHttpProtocol('ftp://root@192.168.1.1') // false
|
||||||
|
```
|
||||||
21
index.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<script>
|
||||||
|
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||||
|
CSS.supports('top: constant(a)'))
|
||||||
|
document.write(
|
||||||
|
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||||
|
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||||
|
</script>
|
||||||
|
<title></title>
|
||||||
|
<!--preload-links-->
|
||||||
|
<!--app-context-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"><!--app-html--></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
75
package.json
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"name": "718yousheng",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev:app": "uni -p app",
|
||||||
|
"dev:app-android": "uni -p app-android",
|
||||||
|
"dev:app-ios": "uni -p app-ios",
|
||||||
|
"dev:custom": "uni -p",
|
||||||
|
"dev:h5": "uni",
|
||||||
|
"dev:h5:ssr": "uni --ssr",
|
||||||
|
"dev:mp-alipay": "uni -p mp-alipay",
|
||||||
|
"dev:mp-baidu": "uni -p mp-baidu",
|
||||||
|
"dev:mp-jd": "uni -p mp-jd",
|
||||||
|
"dev:mp-kuaishou": "uni -p mp-kuaishou",
|
||||||
|
"dev:mp-lark": "uni -p mp-lark",
|
||||||
|
"dev:mp-qq": "uni -p mp-qq",
|
||||||
|
"dev:mp-toutiao": "uni -p mp-toutiao",
|
||||||
|
"dev:mp-weixin": "uni -p mp-weixin",
|
||||||
|
"dev:mp-xhs": "uni -p mp-xhs",
|
||||||
|
"dev:quickapp-webview": "uni -p quickapp-webview",
|
||||||
|
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
|
||||||
|
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
|
||||||
|
"build:app": "uni build -p app",
|
||||||
|
"build:app-android": "uni build -p app-android",
|
||||||
|
"build:app-ios": "uni build -p app-ios",
|
||||||
|
"build:custom": "uni build -p",
|
||||||
|
"build:h5": "uni build",
|
||||||
|
"build:h5:ssr": "uni build --ssr",
|
||||||
|
"build:mp-alipay": "uni build -p mp-alipay",
|
||||||
|
"build:mp-baidu": "uni build -p mp-baidu",
|
||||||
|
"build:mp-jd": "uni build -p mp-jd",
|
||||||
|
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
||||||
|
"build:mp-lark": "uni build -p mp-lark",
|
||||||
|
"build:mp-qq": "uni build -p mp-qq",
|
||||||
|
"build:mp-toutiao": "uni build -p mp-toutiao",
|
||||||
|
"build:mp-weixin": "uni build -p mp-weixin",
|
||||||
|
"build:mp-xhs": "uni build -p mp-xhs",
|
||||||
|
"build:quickapp-webview": "uni build -p quickapp-webview",
|
||||||
|
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
||||||
|
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-app": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-app-harmony": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-app-plus": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-components": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-h5": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-alipay": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-baidu": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-harmony": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-jd": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-kuaishou": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-lark": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-qq": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-toutiao": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-weixin": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-mp-xhs": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-quickapp-webview": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-ui": "^1.5.7",
|
||||||
|
"mescroll-uni": "^1.3.7",
|
||||||
|
"pinia": "2.0.20",
|
||||||
|
"vue": "^3.4.21"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@dcloudio/types": "^3.4.8",
|
||||||
|
"@dcloudio/uni-automator": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-cli-shared": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/uni-stacktracey": "3.0.0-4070520250711001",
|
||||||
|
"@dcloudio/vite-plugin-uni": "3.0.0-4070520250711001",
|
||||||
|
"@vue/runtime-core": "^3.4.21",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"sass": "^1.79.3",
|
||||||
|
"vite": "5.2.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
2
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ignoredBuiltDependencies:
|
||||||
|
- esbuild
|
||||||
7
server/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# node.js
|
||||||
|
|
||||||
|
接口模拟,仅作鉴权演示
|
||||||
|
|
||||||
|
## 移除方法
|
||||||
|
|
||||||
|
- 删除 /server 目录
|
||||||
491
server/index.js
Normal file
@@ -0,0 +1,491 @@
|
|||||||
|
const express = require('express'), http = require('http');
|
||||||
|
|
||||||
|
const cors = require('cors')
|
||||||
|
const app = express()
|
||||||
|
|
||||||
|
app.use(cors())
|
||||||
|
|
||||||
|
const bodyParser = require('body-parser')
|
||||||
|
//读取json配置
|
||||||
|
app.use(bodyParser.json({ limit: '1mb' }))
|
||||||
|
app.use(bodyParser.urlencoded({
|
||||||
|
extended: true
|
||||||
|
}))
|
||||||
|
|
||||||
|
// mockjs
|
||||||
|
const Mock = require('mockjs')
|
||||||
|
|
||||||
|
const img = {"code":0,"msg":"Success","data":{"token":null,"uuid":"bcbe638a-79e4-421d-ba7b-d1c052aca63f","img":"/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAkAG8DASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD26iqWqanDpVp9onV2XcFwgz1qc3dsLQXTTxrbkAiVmAXB6cmoOWztcratHqUlsDps8ccqnJV1zv8AbPb/AD0rKt/FapbTrf27xXsA+aJR9/kDjP1H/wBeqEeqarp2pPbIZbyO4LGH7RG0bA47BsdPToe2KamnahrmspeXlntiRMMsyeWH4OBjkjr3zjn2FBsopL3tiWHVvEWst5mnwR29v2cgEHr/ABHr0xwOO+Kt6Rey6r5sWp3EkU0MnleVFJ5QYjvlcMT1GM46cZ5qvrF1cC8k0+w06dpVwwl81+2DkAHtle/oCKj0Y2kyvbMt9DPE5kuckHeSCDuBHQEg8DOQM8ZyLcppOOx0stxbw7bVzOAFGGw56Y/j9eR3yc9+ahZrcJuhu5nOQCEnBIBOCfmPQDJPfAOMnFUZIrS1k+0pqd40hTYqJNlWywAABOwMS2ATg89cA1jy2eq6tdXEc0jW1mJgpe4+Usx2qAPqcYA45HU8l6ImMU+pZudfvLu6TT9Kl8ySX5TKygbDjJAIODgA8/XGeKp+GFuE1e6KPPPAAwdkJAkII5z0zzkDIJ59DTbsDRLa6jj32sxVUEe5C7AlsOxDE7Tg7cgfdb1wL1peJ4d0pY3mjLFQ7RbcOXOcjrkEY6kY6e9LzNZJJWj1JPE97JHawRQG6tp5JQATIQCOc8g464//AFU2TQL5bZ7i11+eVlXeo3HB/HdWJqN9qF/qlvLeWshCjzY7ZCQQn4cjOOtWr7V7iYSbbWLT3kyWkeXaduMEAcE9PQnPSkHK0lY6DRb3+19NsmunkNykjN+7mMe7bxuYAjcvzAEcjJHHpq7Td+XLuljjKsPLOUY5IweDkcA8HnnnHSua0PVRYwJZ21tPf26hi1xbRNgSZHy8gZ6nnjgD14utP4muj5MOnW1gvzM0zzhznIwFAB565JH5U7swktdDQu7KfUFkt7i5SO3kziOJAXIHqzZHvwoIOOeOeck0bU9DvXuNPtoryGFN8bSxqzpndkL/ABZxnpjO7vzXWSwzef50Mqqdu0oyjDYPGT17n86g8yWO6826t1wqbEeOPcRk5bnOdpwnGB908nimtxQk0mmYVhYX15d2mo6jJDanaFtLbZtx8pONpwQQATjrxz0rbee7gdmukiMBKBTE207t3ck85+UAevHOcB02sWcMYbzNxzjYB8wPPUdulR211p7adHbfabYKIhEREPLUcAYVSTtHtzjp2pLTYp8zV2tCnc6lFbAwTzCJNg803cO7zycgj5T14HbGDx7ZuhveXuqXurRRZVovKVmwckADdgY3fdyQMfhUtpoOhRyTFpRIUYCMyyZB+UHJAC9z0yRx1zkDZS102PIgMCSs+d0bKhz0/hHOAMD6Y9aNUU3GOiQ6U2E0qSz277kBC74mxzjtjGeB7847kVAiWuyDF+sbrzKY2KLJ8pzgEnaM89T9ec02+t4LW3llu7i2KPjc86/OSrF1AYHOVYsVA5BHGKiS+1TV4f8AQLWK2jJH+lXCk5XPVEwCeMEE8e1VdkejOf8AE17cw6zB5h82K3AeJnX5WJwc8de35UaZHJfzNfLbvql1uy5cmOMDHRWOPmBK/hnHY101n4dgicy3shvZjn76BYx24QcDjHXPTtWzUlOqrWRwtlpL61reoxX0rRrGhif7M5xzxty2cjAIINdXaaJptkgWCzjG1t6lxvII6YLZIq/RQtCJTcgooooMyCMhb2eNURcqkjEDBZjlcn14UD8Km2jcWwMkYJoooFHYZJbwy/6yJH/3lB/z0FZ9xo1mY2YKy4BwAc+p70UUzWDdzAuYlguvLTpnqfZiKz727khgeWJUSXaMuF5YDOFOeo5P+SclFUdb2Oq0bTLX7Jb3zoZLiWNZCznIUkBvlHQc9O9bNFFSzjm/eCiiikQFFFFABRRRQB//2Q==","platform":null,"currencyUnit":null,"exchangeRate":null,"countryCode":null,"usRate":null}};
|
||||||
|
app.get('/api/captchaImage', (req,res,next) =>{
|
||||||
|
res.end(JSON.stringify(img));
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取验证码
|
||||||
|
app.post('/api/sendSms', (req, res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
verifyCode:'123456'
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 登录
|
||||||
|
app.post('/api/user/login',(req,res,next) => {
|
||||||
|
const { loginType,phone,verifyCode,username, password } = req.body;
|
||||||
|
let retObj = {
|
||||||
|
code: 0,
|
||||||
|
message: '登录成功',
|
||||||
|
data: {
|
||||||
|
'id': '@id',
|
||||||
|
'name': '@cname',
|
||||||
|
'token': '@guid',
|
||||||
|
'avatar': '@image("100x100", "#4A7BF7", "avatar")',
|
||||||
|
'roles|1': ['admin', 'editor', 'visitor']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("/api/user/login=>",loginType,phone,verifyCode,username, password)
|
||||||
|
// console.log("/api/user/login=>",Mock.mock(retObj))
|
||||||
|
|
||||||
|
if(loginType===0){//验证码登录
|
||||||
|
if (phone === '15112345600' && verifyCode === '123456') {
|
||||||
|
res.json(Mock.mock(retObj))
|
||||||
|
} else {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 401,
|
||||||
|
message: '验证码错误'
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}else if(loginType===1){//用户名密码登录
|
||||||
|
if (username === 'admin' && password === '123456') {
|
||||||
|
res.json(Mock.mock(retObj))
|
||||||
|
} else {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 401,
|
||||||
|
message: '用户名或密码错误'
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: -1,
|
||||||
|
msg: '请正确输入登录信息'
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
app.post('/api/getUserInfo', (req,res) => {
|
||||||
|
// console.log("req=>",req)
|
||||||
|
// reqBody = JSON.parse(req.body)
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
'id': '@id',
|
||||||
|
'name': '小北',
|
||||||
|
'token': '@guid',
|
||||||
|
'avatar': '@image("100x100", "#4A7BF7", "avatar")',
|
||||||
|
'deptName':'数字信息服务中心',
|
||||||
|
'jobName':'副总经理',
|
||||||
|
'joinDay':1953,
|
||||||
|
'level':5
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 搜索功能
|
||||||
|
app.post('/api/search', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
'id': '@id',
|
||||||
|
'content': '@cname',
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 查询企业日常 Daily business
|
||||||
|
app.post('/api/businessDaily', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{id:1,name:'任务计划',imgSrc:'static/images/business/icon-rwjh.png'},
|
||||||
|
{id:2,name:'日报',imgSrc:'static/images/business/icon-rb.png'},
|
||||||
|
{id:3,name:'设备管理',imgSrc:'static/images/business/icon-sbgl.png'},
|
||||||
|
{id:4,name:'绩效管理',imgSrc:'static/images/business/icon-jxgl.png'},
|
||||||
|
{id:5,name:'公章申请',imgSrc:'static/images/business/icon-gzsq.png'},
|
||||||
|
{id:6,name:'会议室预约',imgSrc:'static/images/business/icon-hysyy.png'},
|
||||||
|
{id:7,name:'报修',imgSrc:'static/images/business/icon-bx.png'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 查询CRM系统 Daily business
|
||||||
|
app.post('/api/businessCRMList', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{id:1,name:'走访报告',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/visitorReport'},
|
||||||
|
{id:2,name:'走访报告添加',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/visitorReportAdd'},
|
||||||
|
{id:3,name:'走访报告详情',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/visitorReportDetail'},
|
||||||
|
{id:4,name:'走访报告内容录入',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/visitorReportEnter'},
|
||||||
|
{id:5,name:'市场信息管理',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/marketInformation'},
|
||||||
|
{id:6,name:'修改周计划',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/weekPlanUpdate'},
|
||||||
|
{id:7,name:'签到打卡',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/vistorCheckin'},
|
||||||
|
{id:8,name:'打卡统计',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/checkinStatistics'},
|
||||||
|
{id:9,name:'回款查看',imgSrc:'static/images/business/demo.png',url:'/pages/business/CRM/paymentCollection'},
|
||||||
|
{id:101,name:'走访报告',imgSrc:'static/images/business/icon-zfbg.png'},
|
||||||
|
{id:102,name:'走访查看',imgSrc:'static/images/business/icon-zfck.png'},
|
||||||
|
{id:103,name:'走访审批',imgSrc:'static/images/business/icon-zfsp.png'},
|
||||||
|
{id:104,name:'计划查看',imgSrc:'static/images/business/icon-jhck.png'},
|
||||||
|
{id:105,name:'签到打卡',imgSrc:'static/images/business/icon-qddk.png'},
|
||||||
|
{id:106,name:'打卡信息',imgSrc:'static/images/business/icon-dkxx.png'},
|
||||||
|
{id:107,name:'打卡统计',imgSrc:'static/images/business/icon-dktj.png'},
|
||||||
|
{id:108,name:'人员新增',imgSrc:'static/images/business/icon-ryxz.png'},
|
||||||
|
{id:109,name:'信息查看',imgSrc:'static/images/business/icon-xxck.png'},
|
||||||
|
{id:1010,name:'信息审核',imgSrc:'static/images/business/xxsh.png',badgeCount:5},
|
||||||
|
{id:1011,name:'信息统计',imgSrc:'static/images/business/icon-xxtj.png'},
|
||||||
|
{id:1012,name:'回款查看',imgSrc:'static/images/business/icon-hkck.png'},
|
||||||
|
{id:1013,name:'客户人员审核',imgSrc:'static/images/business/icon-khrysh.png',badgeCount:3},
|
||||||
|
{id:1014,name:'客户人员所属',imgSrc:'static/images/business/icon-khryss.png'},
|
||||||
|
{id:1015,name:'客户人员归属人变更',imgSrc:'static/images/business/icon-khrybg.png'},
|
||||||
|
{id:1016,name:'市场活动',imgSrc:'static/images/business/icon-schd.png'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 首页待办数据
|
||||||
|
app.post('/api/backBlogCount', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
count1:3,
|
||||||
|
count2:7,
|
||||||
|
count3:2,
|
||||||
|
count4:6,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 首页通知消息跑马灯
|
||||||
|
app.post('/api/swiperList', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: ["祝贺“友晟夏季封装外壳发布会”圆满成功","祝贺“友晟科技发布会”圆满成功","祝贺“友晟夏季封装外壳发布会”圆满成功"]
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 首页日程提醒
|
||||||
|
app.post('/api/stepData', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
date:new Date().getTime(),
|
||||||
|
list:[
|
||||||
|
{ id:1,desc: '2025秋季产品发布前期准备会,在科研楼0317会议室召开。', title: '13:30 — 15:30',beginTime:'13:30',endTime:'15:30'},
|
||||||
|
{ id:2,desc: '生产间安全巡检。', title: '16:30 — 18:00',beginTime:'16:30',endTime:'18:00'},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 首页销售任务
|
||||||
|
app.post('/api/salesTask', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
salesList:['2025-3季度', '2025-2季度', '2025-1季度'],
|
||||||
|
percentNum:82,
|
||||||
|
totalSales:62075000,
|
||||||
|
targetSales:75000000
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 首页常用服务
|
||||||
|
app.post('/api/commonServices', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{id:1,name:'设备管理',imgSrc:'static/images/business/icon-sbgl.png'},
|
||||||
|
{id:2,name:'目标管理',imgSrc:'static/images/business/icon-mbgl.png'},
|
||||||
|
{id:3,name:'科研工艺',imgSrc:'static/images/business/icon-kygy.png'},
|
||||||
|
{id:4,name:'工艺攻关',imgSrc:'static/images/business/icon-gygg.png'},
|
||||||
|
{id:5,name:'数据采集',imgSrc:'static/images/business/icon-sjcj.png'}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 新闻列表
|
||||||
|
app.post('/api/newsQueryList', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{id:1,date:'2025-06-29',name:'友晟亮相2025慕尼黑上海电子展',imgSrc:'https://img2.baidu.com/it/u=363858033,1221485415&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1067'},
|
||||||
|
{id:2,date:'2025-06-26',name:'孜孜不倦,谱写公司发展新篇章',imgSrc:'https://img0.baidu.com/it/u=2830423559,3962669886&fm=253&app=138&f=JPEG?w=570&h=760'},
|
||||||
|
{id:3,date:'2025-03-29 08:10:00',name:'质量管理体系提升助力实现质的飞跃',imgSrc:''},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
// 消息列表
|
||||||
|
app.post('/api/noticeList', (req,res) => {
|
||||||
|
// console.log(req.body)
|
||||||
|
let param = req.body;
|
||||||
|
if(param.pageIndex==1){
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{id:1,date:'2025-06-30',isReady:true,title:'临时调整本周工作时间的通知',imgSrc:'static/images/notice/icon-TiXing@2x.png'},
|
||||||
|
{id:2,date:'2025-06-27',isReady:false,title:'8月个税扣缴申报已完成',imgSrc:'static/images/notice/icon-RiCheng@2x.png'},
|
||||||
|
{id:3,date:'2025-09-10 17:29:00',isReady:true,title:'公司班车北五环线路调整的通知',imgSrc:'static/images/notice/icon-DaiBan@2x.png'},
|
||||||
|
{id:4,date:'2025-09-09 15:36:00',isReady:true,title:'祝贺“友晟夏季封装外壳发布会”圆满成功',imgSrc:'static/images/notice/icon-TongZhi@2x.png'},
|
||||||
|
{id:5,date:'2025-09-07 08:41:00',isReady:false,title:'研发部采购验收流程【2025】修改版',imgSrc:'static/images/notice/icon-FuWu@2x.png'},
|
||||||
|
{id:6,date:'2025-09-07 08:08:00',isReady:false,title:'加强公司安全管理 迎接全市年度检查',imgSrc:'static/images/notice/icon-TongZhi@2x.png'},
|
||||||
|
{id:7,date:'2025-09-05 13:18:00',isReady:false,title:'2025年国庆节放假安排通知',imgSrc:'static/images/notice/icon-TiXing@2x.png'},
|
||||||
|
{id:8,date:'2025-06-30',isReady:true,title:'临时调整本周工作时间的通知',imgSrc:'static/images/notice/icon-TiXing@2x.png'},
|
||||||
|
{id:9,date:'2025-06-27',isReady:false,title:'8月个税扣缴申报已完成',imgSrc:'static/images/notice/icon-RiCheng@2x.png'},
|
||||||
|
{id:10,date:'2025-09-10 17:29:00',isReady:true,title:'公司班车北五环线路调整的通知',imgSrc:'static/images/notice/icon-DaiBan@2x.png'},
|
||||||
|
// {id:11,date:'2025-09-09 15:36:00',isReady:true,title:'祝贺“友晟夏季封装外壳发布会”圆满成功',imgSrc:'static/images/notice/icon-TongZhi@2x.png'},
|
||||||
|
// {id:12,date:'2025-09-07 08:41:00',isReady:false,title:'研发部采购验收流程【2025】修改版',imgSrc:'static/images/notice/icon-FuWu@2x.png'},
|
||||||
|
// {id:13,date:'2025-09-07 08:08:00',isReady:false,title:'加强公司安全管理 迎接全市年度检查',imgSrc:'static/images/notice/icon-TongZhi@2x.png'},
|
||||||
|
// {id:14,date:'2025-09-05 13:18:00',isReady:false,title:'2025年国庆节放假安排通知',imgSrc:'static/images/notice/icon-TiXing@2x.png'},
|
||||||
|
],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}else if(param.pageIndex==2){
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{id:11,date:'2025-09-09 15:36:00',isReady:true,title:'祝贺“友晟夏季封装外壳发布会”圆满成功',imgSrc:'static/images/notice/icon-TongZhi@2x.png'},
|
||||||
|
{id:12,date:'2025-09-07 08:41:00',isReady:false,title:'研发部采购验收流程【2025】修改版',imgSrc:'static/images/notice/icon-FuWu@2x.png'},
|
||||||
|
{id:13,date:'2025-09-07 08:08:00',isReady:false,title:'加强公司安全管理 迎接全市年度检查',imgSrc:'static/images/notice/icon-TongZhi@2x.png'},
|
||||||
|
{id:14,date:'2025-09-05 13:18:00',isReady:false,title:'2025年国庆节放假安排通知',imgSrc:'static/images/notice/icon-TiXing@2x.png'},
|
||||||
|
],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}else{
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 走访报告列表
|
||||||
|
app.post('/api/visitorReportList', (req,res) => {
|
||||||
|
let param = req.body;
|
||||||
|
// console.log(param)
|
||||||
|
if(param.pageIndex==1){
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{
|
||||||
|
id:1,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:2,title:'客户:中国船舶集团有限公司第七一 七研究所',name:'YS-VR2025091307',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:3,title:'客户:旭日阳(北京)科技有限公司',name:'YS-VR2025090902',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:4,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:5,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:6,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:7,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:8,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:9,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:10,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}else if(param.pageIndex==2){
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{
|
||||||
|
id:11,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:12,title:'客户:中国船舶集团有限公司第七一 七研究所',name:'YS-VR2025091307',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:13,title:'客户:旭日阳(北京)科技有限公司',name:'YS-VR2025090902',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:14,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
reportType:1,reportTypeName:'I 类活动 (走访)',statusName:'待胡本华审核',
|
||||||
|
reportPeople:'管理员',dateStr:'2025-09-15'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}else{
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 客户列表
|
||||||
|
app.post('/api/guestList', (req,res) => {
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{id:1,name:'西安微电子技术研究所'},
|
||||||
|
{id:2,name:'西安微电子技术研究所2'},
|
||||||
|
{id:3,name:'旭日阳(北京)科技有限公司'},
|
||||||
|
{id:4,name:'北京中科睿信科技有限公司'},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
// 走访报告详情
|
||||||
|
app.post('/api/visitorReportDetail', (req,res) => {
|
||||||
|
let param = req.body;
|
||||||
|
// console.log(111,param.id)
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
activeObj:{
|
||||||
|
id:1,title:'客户:北京中科睿信科技有限公司',name:'YS-VR2025091515',
|
||||||
|
isJoin:'否',activityType:1,activityTypeName:'I 类活动 (走访)',
|
||||||
|
dateStr:'2025-09-10',reportPeople:'刘启运'
|
||||||
|
},
|
||||||
|
reportObj:{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
// 重大事项信息
|
||||||
|
app.post('/api/mattersList', (req,res) => {
|
||||||
|
let param = req.body;
|
||||||
|
// console.log(param)
|
||||||
|
if(param.pageIndex==1){
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{ id:1,status:1,statusName:'待王彦琳审核',title:'西安微电子技术研究所',desc:'a该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:2,status:1,statusName:'待曾诚审核',title:'中国船舶集团有限公司第七研究所',desc:'b该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:3,status:2,statusName:'完成',title:'旭日阳(北京)科技有限公司',desc:'c该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:4,status:2,statusName:'完成',title:'北京中科睿信科技有限公司',desc:'d该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:5,status:1,statusName:'待王彦琳审核',title:'旭日阳(北京)科技有限公司',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:6,status:1,statusName:'待曾诚审核',title:'北京中科睿信科技有限公司',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:7,status:1,statusName:'待王彦琳审核',title:'旭日阳(北京)科技有限公司',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:8,status:1,statusName:'待王彦琳审核',title:'北京中科睿信科技有限公司',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:9,status:1,statusName:'待王彦琳审核',title:'旭日阳(北京)科技有限公司',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:10,status:1,statusName:'待王彦琳审核',title:'中国船舶集团有限公司第七研究所',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}else if(param.pageIndex==2){
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[
|
||||||
|
{ id:11,status:1,statusName:'待王彦琳审核',title:'北京中科睿信科技有限公司',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:12,status:1,statusName:'待王彦琳审核',title:'中国船舶集团有限公司第七研究所',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:13,status:1,statusName:'待王彦琳审核',title:'旭日阳(北京)科技有限公司',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
{ id:14,status:1,statusName:'待王彦琳审核',title:'北京中科睿信科技有限公司',desc:'该企业产品线技术改造延期,本月设备供应周期预 计延长7-15天。' },
|
||||||
|
],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}else{
|
||||||
|
res.json(Mock.mock({
|
||||||
|
code: 0,
|
||||||
|
data: {
|
||||||
|
list:[],
|
||||||
|
totalCount:14
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//2.创建server
|
||||||
|
const server = http.createServer(app);
|
||||||
|
|
||||||
|
|
||||||
|
//3.监听端口
|
||||||
|
server.listen(3000, () => {
|
||||||
|
console.log('服务器运行在 http://localhost:3000')
|
||||||
|
})
|
||||||
|
|
||||||
799
server/package-lock.json
generated
Normal file
@@ -0,0 +1,799 @@
|
|||||||
|
{
|
||||||
|
"name": "server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^5.1.0",
|
||||||
|
"mockjs": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/accepts": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/accepts/-/accepts-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"negotiator": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "^3.1.2",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"iconv-lite": "^0.6.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"raw-body": "^3.0.0",
|
||||||
|
"type-is": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bytes": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/call-bind-apply-helpers": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/call-bound": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"get-intrinsic": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/commander": {
|
||||||
|
"version": "14.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/commander/-/commander-14.0.0.tgz",
|
||||||
|
"integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-disposition": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "5.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-type": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie-signature": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dunder-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"gopd": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||||
|
},
|
||||||
|
"node_modules/encodeurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-define-property": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-errors": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-object-atoms": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
||||||
|
},
|
||||||
|
"node_modules/etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/express/-/express-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "^2.0.0",
|
||||||
|
"body-parser": "^2.2.0",
|
||||||
|
"content-disposition": "^1.0.0",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"cookie": "^0.7.1",
|
||||||
|
"cookie-signature": "^1.2.1",
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"finalhandler": "^2.1.0",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"merge-descriptors": "^2.0.0",
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"once": "^1.4.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"proxy-addr": "^2.0.7",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"router": "^2.2.0",
|
||||||
|
"send": "^1.1.0",
|
||||||
|
"serve-static": "^2.2.0",
|
||||||
|
"statuses": "^2.0.1",
|
||||||
|
"type-is": "^2.0.1",
|
||||||
|
"vary": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/finalhandler": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"statuses": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/forwarded": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fresh": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/fresh/-/fresh-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/function-bind": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-intrinsic": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"es-define-property": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"es-object-atoms": "^1.1.1",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-proto": "^1.0.1",
|
||||||
|
"gopd": "^1.2.0",
|
||||||
|
"has-symbols": "^1.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"math-intrinsics": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||||
|
"dependencies": {
|
||||||
|
"dunder-proto": "^1.0.1",
|
||||||
|
"es-object-atoms": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gopd": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-symbols": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hasown": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-errors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"toidentifier": "1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-errors/node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/iconv-lite": {
|
||||||
|
"version": "0.6.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
|
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"node_modules/ipaddr.js": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-promise": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/is-promise/-/is-promise-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
|
||||||
|
},
|
||||||
|
"node_modules/math-intrinsics": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/media-typer": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/merge-descriptors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.54.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz",
|
||||||
|
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "^1.54.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mockjs": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/mockjs/-/mockjs-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "*"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"random": "bin/random"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
},
|
||||||
|
"node_modules/negotiator": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-inspect": {
|
||||||
|
"version": "1.13.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
|
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/on-finished": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||||
|
"dependencies": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/parseurl": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "8.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
|
||||||
|
"integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/proxy-addr": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||||
|
"dependencies": {
|
||||||
|
"forwarded": "0.2.0",
|
||||||
|
"ipaddr.js": "1.9.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.14.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.14.0.tgz",
|
||||||
|
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/range-parser": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"iconv-lite": "0.6.3",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/router": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/router/-/router-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"depd": "^2.0.0",
|
||||||
|
"is-promise": "^4.0.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"path-to-regexp": "^8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
|
},
|
||||||
|
"node_modules/send": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/send/-/send-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.5",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"mime-types": "^3.0.1",
|
||||||
|
"ms": "^2.1.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"statuses": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/serve-static": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"send": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
|
},
|
||||||
|
"node_modules/side-channel": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"object-inspect": "^1.13.3",
|
||||||
|
"side-channel-list": "^1.0.0",
|
||||||
|
"side-channel-map": "^1.0.1",
|
||||||
|
"side-channel-weakmap": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-list": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"object-inspect": "^1.13.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-map": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bound": "^1.0.2",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.5",
|
||||||
|
"object-inspect": "^1.13.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-weakmap": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bound": "^1.0.2",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.5",
|
||||||
|
"object-inspect": "^1.13.3",
|
||||||
|
"side-channel-map": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/statuses": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/toidentifier": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/type-is": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/type-is/-/type-is-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
||||||
|
"dependencies": {
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"media-typer": "^1.1.0",
|
||||||
|
"mime-types": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
server/package.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^5.1.0",
|
||||||
|
"mockjs": "^1.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/App.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onLaunch } from '@dcloudio/uni-app';
|
||||||
|
onLaunch((opt) => {
|
||||||
|
console.log("onLaunch")
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
@import '@/static/common.css';
|
||||||
|
|
||||||
|
</style>
|
||||||
37
src/api/auth.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import request from "@/utils/request"
|
||||||
|
|
||||||
|
|
||||||
|
// 获取图片
|
||||||
|
export function getCaptchaImage() {
|
||||||
|
return request.get({
|
||||||
|
url: '/api/captchaImage',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取验证码
|
||||||
|
export function getVerifyCode(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/sendSms',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录
|
||||||
|
export function login(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/user/login',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
export function getUserInfo(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/getUserInfo',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
57
src/api/business.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import request from "@/utils/request"
|
||||||
|
|
||||||
|
// 搜索查询
|
||||||
|
export function search(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/search',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 企业日常
|
||||||
|
export function businessDaily(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/businessDaily',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRM 列表
|
||||||
|
export function businessCRMList(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/businessCRMList',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRM 查询走访报告列表
|
||||||
|
export function visitorReportList(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/visitorReportList',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRM 客户列表
|
||||||
|
export function getGuestList(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/guestList',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRM 查询走访报告详情
|
||||||
|
export function visitorReportDetail(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/visitorReportDetail',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRM 查询走访报告列表
|
||||||
|
export function mattersList(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/mattersList',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
49
src/api/home.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import request from "@/utils/request"
|
||||||
|
|
||||||
|
// 待办数据查询
|
||||||
|
export function backBlogCount(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/backBlogCount',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跑马灯列表
|
||||||
|
export function swiperList(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/swiperList',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日程提醒
|
||||||
|
export function stepData(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/stepData',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 销售任务
|
||||||
|
export function salesTask(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/salesTask',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 常用服务
|
||||||
|
export function commonServices(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/commonServices',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新闻公告
|
||||||
|
export function newsQueryList(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/newsQueryList',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
9
src/api/notice.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import request from "@/utils/request"
|
||||||
|
|
||||||
|
// 查询通知列表
|
||||||
|
export function noticeList(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/api/noticeList',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
111
src/components/customHeader.vue
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<view class="custom-navbar">
|
||||||
|
<view class="navbar-main" :style="{paddingTop:navBarPaddingTop+'px'}">
|
||||||
|
<!-- 左侧内容 -->
|
||||||
|
<view class="navbar-left" @click="handleBack" v-if="leftFlag">
|
||||||
|
<uni-icons type="left" size="24" color="#fff"></uni-icons>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 中间标题 -->
|
||||||
|
<view class="navbar-title">{{ title }}</view>
|
||||||
|
|
||||||
|
<!-- 右侧内容 -->
|
||||||
|
<view class="navbar-right" v-if="rightFlag">
|
||||||
|
<slot name="right"></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { getNavBarPaddingTop,getNavBarHeight,getStatusBarHeight} from '@/utils/system.js'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
title: String,
|
||||||
|
leftFlag:true,//默认左侧显示 false-不显示
|
||||||
|
rightFlag:false,//默认右侧不显示
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['back'])
|
||||||
|
|
||||||
|
let navBarPaddingTop = ref(0)
|
||||||
|
let statusBarHeight = ref(0)
|
||||||
|
let navbarHeight = ref(0)
|
||||||
|
let navHeight = ref(0)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop();console.log(navBarPaddingTop.value)
|
||||||
|
statusBarHeight.value = getStatusBarHeight();
|
||||||
|
navbarHeight.value = getNavBarHeight();
|
||||||
|
navHeight.value = navbarHeight.value - statusBarHeight.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
emit('back')
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.custom-navbar {
|
||||||
|
width: 750rpx;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
margin-left:-375rpx;
|
||||||
|
z-index: 999;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
background: url('@/static/images/bg-Blue-header.png') no-repeat;
|
||||||
|
background-size:750rpx 160rpx;
|
||||||
|
height:160rpx;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
background: url('@/static/images/bg-Blue-header2.png') no-repeat;
|
||||||
|
background-size:750rpx 116rpx;
|
||||||
|
height:116rpx;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-main {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color:#fff;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:160rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height:116rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-left{
|
||||||
|
width: 70rpx;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-title {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
color:#fff;
|
||||||
|
margin-top:-3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-right{
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
84
src/components/customSearch.vue
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<!-- 搜索框 -->
|
||||||
|
<uni-search-bar v-model="searchText" @confirm="handleSearch" />
|
||||||
|
|
||||||
|
<!-- <view v-if="showSuggestions" class="suggestions-list">
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in suggestions"
|
||||||
|
:key="index"
|
||||||
|
class="suggestion-item"
|
||||||
|
@click="selectSuggestion(item)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
<!-- 筛选条件 -->
|
||||||
|
<view class="filter-container">
|
||||||
|
<picker mode="selector" :range="categoryOptions" @change="handleCategoryChange">
|
||||||
|
<view class="filter-item">{{ categoryText }}</view>
|
||||||
|
</picker>
|
||||||
|
<picker mode="selector" :range="sortOptions" @change="handleSortChange">
|
||||||
|
<view class="filter-item">{{ sortText }}</view>
|
||||||
|
</picker>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 搜索结果 -->
|
||||||
|
<search-results :list="results" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
|
// const suggestions = ref([])
|
||||||
|
// const showSuggestions = ref(false)
|
||||||
|
|
||||||
|
// const handleInput = debounce(async () => {
|
||||||
|
// if (!searchText.value.trim()) {
|
||||||
|
// showSuggestions.value = false
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const res = await getSuggestions(searchText.value)
|
||||||
|
// suggestions.value = res
|
||||||
|
// showSuggestions.value = true
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('获取搜索建议失败:', error)
|
||||||
|
// }
|
||||||
|
// }, 300)
|
||||||
|
|
||||||
|
const searchText = ref('')
|
||||||
|
const category = ref(0)
|
||||||
|
const sort = ref(0)
|
||||||
|
|
||||||
|
const categoryOptions = ['全部类别', '电子产品', '服装', '食品']
|
||||||
|
const sortOptions = ['默认排序', '价格从低到高', '价格从高到低', '销量最高']
|
||||||
|
|
||||||
|
const categoryText = computed(() => categoryOptions[category.value])
|
||||||
|
const sortText = computed(() => sortOptions[sort.value])
|
||||||
|
|
||||||
|
const handleSearch = async () => {
|
||||||
|
const params = {
|
||||||
|
keyword: searchText.value,
|
||||||
|
category: category.value,
|
||||||
|
sort: sort.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用搜索API
|
||||||
|
const res = await searchAPI(params)
|
||||||
|
results.value = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCategoryChange = (e) => {
|
||||||
|
category.value = e.detail.value
|
||||||
|
handleSearch()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSortChange = (e) => {
|
||||||
|
sort.value = e.detail.value
|
||||||
|
handleSearch()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
137
src/components/customSteps.vue
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<template>
|
||||||
|
<view class="vertical-step-progress">
|
||||||
|
<view v-for="(step, index) in steps" :key="index" class="step-item">
|
||||||
|
<view class="step-connector" :style="{ backgroundColor: index < activeStep ? activeColor : inactiveColor2 }"></view>
|
||||||
|
<view class="step-icon" :style="{ backgroundColor: index < activeStep ? activeColor : inactiveColor }">
|
||||||
|
<text v-if="index < activeStep">✓</text>
|
||||||
|
<!-- <text v-else>{{ index + 1 }}</text> -->
|
||||||
|
</view>
|
||||||
|
<view class="step-content">
|
||||||
|
<text class="step-title">
|
||||||
|
<text class="font-blue">{{ step.beginTime }}</text> — <text class="font-blue">{{ step.endTime }}</text>
|
||||||
|
</text>
|
||||||
|
<text class="step-desc">{{ step.desc }}</text>
|
||||||
|
</view>
|
||||||
|
<!-- <view class="btn-round-red" @click="handleDelete(index)">
|
||||||
|
<uni-icons type="trash" size="20" color="#fff"></uni-icons>
|
||||||
|
</view> -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// import { ref } from 'vue';
|
||||||
|
import { showAlert } from '@/utils/message.js';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
steps: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
activeStep: {
|
||||||
|
type: Number,
|
||||||
|
default: -1
|
||||||
|
},
|
||||||
|
activeColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#4cd964'
|
||||||
|
},
|
||||||
|
inactiveColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#ffffff'
|
||||||
|
},
|
||||||
|
inactiveColor2:{
|
||||||
|
type: String,
|
||||||
|
default: '#E6E6E6'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
// 删除日程提醒
|
||||||
|
const handleDelete = (index) => {
|
||||||
|
showAlert("是否确认删除?","提示",true,()=>{
|
||||||
|
props.steps.splice(index,1);
|
||||||
|
emit('update:modelValue', props.steps)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.vertical-step-progress {
|
||||||
|
margin: 30rpx 0rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-connector {
|
||||||
|
position: absolute;
|
||||||
|
left: 4px;
|
||||||
|
top: 0px;
|
||||||
|
width: 2px;
|
||||||
|
height: 160rpx;
|
||||||
|
transform:translate(0px, -8px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item:last-child .step-connector {
|
||||||
|
height: 100rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-icon {
|
||||||
|
width:1px;
|
||||||
|
height: 1px;
|
||||||
|
padding:3px;
|
||||||
|
border:2px solid #E6E6E6;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 15px;
|
||||||
|
color: white;
|
||||||
|
font-size: 14px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #BFBFBF;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
margin-top:-5px;
|
||||||
|
}
|
||||||
|
.step-title .font-blue{
|
||||||
|
color:#05A3F4;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-desc{
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
height:120rpx;
|
||||||
|
width: 500rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item:last-child .step-desc{
|
||||||
|
height:70rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-round-red{
|
||||||
|
background-color: #FF687A;
|
||||||
|
color:#fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
width:56rpx;
|
||||||
|
height: 56rpx;
|
||||||
|
line-height: 56rpx;
|
||||||
|
text-align: center;
|
||||||
|
margin-top:30rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
67
src/components/customTabs.vue
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<!-- components/customTabs.vue -->
|
||||||
|
<template>
|
||||||
|
<view class="tabs-container">
|
||||||
|
<view class="tabs-scorll">
|
||||||
|
<view class="tabs-header">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index"
|
||||||
|
:class="['tab-item', { 'active': modelValue === index }]"
|
||||||
|
@click="switchTab(index)"
|
||||||
|
>
|
||||||
|
{{ tab }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
tabs: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
|
const switchTab = (index) => {
|
||||||
|
emit('update:modelValue', index)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.tabs-header {
|
||||||
|
display: flex;
|
||||||
|
height: 80rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1rpx solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
color: #007AFF;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 60rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
461
src/components/multipleSelect.vue
Normal file
@@ -0,0 +1,461 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <view class="uni-select-dc" :style="{ 'z-index': zindex }"> :style="{ 'z-index': zindex }"-->
|
||||||
|
<view class="uni-select-dc">
|
||||||
|
<view class="uni-select-dc-select" :class="{ active: active }" @click.stop="handleSelect">
|
||||||
|
<!-- 禁用mask -->
|
||||||
|
<view class="uni-disabled" v-if="disabled"></view>
|
||||||
|
<!-- 清空 -->
|
||||||
|
<view class="close-icon close-postion" v-if="realValue.length && !active && !disabled && showClearIcon">
|
||||||
|
<text @click.stop="handleRemove(null)"></text>
|
||||||
|
</view>
|
||||||
|
<!-- 显示框 -->
|
||||||
|
<view class="uni-select-multiple" v-show="realValue.length">
|
||||||
|
<block v-if="multiple" >
|
||||||
|
<view class="uni-select-multiple-item" v-for="(item, index) in changevalue" :key="index">
|
||||||
|
{{ item.text }}
|
||||||
|
<view class="close-icon" v-if="showValueClear">
|
||||||
|
<text @click.stop="handleRemove(index)"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<!-- 单选时展示内容 -->
|
||||||
|
<view v-else class="single-text">
|
||||||
|
{{ changevalue.length ? changevalue[0].text : "" }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 为空时的显示文案 -->
|
||||||
|
<view v-if="realValue.length == 0 && showplaceholder">{{ placeholder }}</view>
|
||||||
|
<!-- 右边的下拉箭头 -->
|
||||||
|
<view :class="{ disabled: disabled, 'uni-select-dc-icon': !downInner, 'uni-select-dc-inner': downInner }">
|
||||||
|
<text></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 下拉选项 -->
|
||||||
|
<scroll-view class="uni-select-dc-options" :scroll-y="true" v-show="active">
|
||||||
|
<view class="uni-select-dc-item" :class="{ active: realValue.includes(item[svalue]) }"
|
||||||
|
v-for="(item, index) in options" :key="index"
|
||||||
|
@click.stop="handleChange(index, item)"
|
||||||
|
>
|
||||||
|
{{ item[slabel] }}
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, reactive, ref } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 是否显示全部清空按钮
|
||||||
|
showClearIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 是否多选
|
||||||
|
multiple: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 下拉箭头是否在框内
|
||||||
|
downInner: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
// 是否显示单个删除
|
||||||
|
showValueClear: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
zindex: {
|
||||||
|
type: Number,
|
||||||
|
default: 999,
|
||||||
|
},
|
||||||
|
// 禁用选择
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: "请选择",
|
||||||
|
},
|
||||||
|
showplaceholder: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
// 默认取text
|
||||||
|
slabel: {
|
||||||
|
type: String,
|
||||||
|
default: "text",
|
||||||
|
},
|
||||||
|
// 默认取value
|
||||||
|
svalue: {
|
||||||
|
type: String,
|
||||||
|
default: "value",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const emit = defineEmits(["change"]);
|
||||||
|
const active = ref(false); // 组件是否激活,
|
||||||
|
let changevalue = reactive([]);
|
||||||
|
let realValue = reactive([]);
|
||||||
|
onMounted(() => {
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化函数
|
||||||
|
const init = () => {
|
||||||
|
if (props.value.length > 0) {
|
||||||
|
props.options.forEach((item) => {
|
||||||
|
props.value.forEach((i) => {
|
||||||
|
if (item[props.svalue] === i) {
|
||||||
|
changevalue.push(item);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
realValue = props.value;
|
||||||
|
console.log("props---", changevalue);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
changevalue = [];
|
||||||
|
realValue = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 点击展示选项
|
||||||
|
const handleSelect = () => {
|
||||||
|
if (props.disabled) return;
|
||||||
|
active.value = !active.value;
|
||||||
|
};
|
||||||
|
// 移除数据
|
||||||
|
const handleRemove = (index) => {
|
||||||
|
if (index === null) {
|
||||||
|
realValue = [];
|
||||||
|
changevalue = [];
|
||||||
|
} else {
|
||||||
|
realValue.splice(index, 1);
|
||||||
|
changevalue.splice(index, 1);
|
||||||
|
}
|
||||||
|
emit("change", changevalue, realValue);
|
||||||
|
};
|
||||||
|
// 点击组件某一项
|
||||||
|
const handleChange = (index, item) => {
|
||||||
|
console.log("选中了某一项", index, item);
|
||||||
|
// 如果是单选框,选中一项后直接关闭
|
||||||
|
if (!props.multiple) {
|
||||||
|
console.log("关闭下拉框");
|
||||||
|
changevalue.length = 0
|
||||||
|
realValue.length = 0
|
||||||
|
changevalue.push(item);
|
||||||
|
realValue.push(item[props.svalue])
|
||||||
|
active.value = !active.value;
|
||||||
|
} else {
|
||||||
|
// 多选操作
|
||||||
|
const arrIndex = realValue.indexOf(item[props.svalue]);
|
||||||
|
if (arrIndex > -1) {
|
||||||
|
// 如果该选项已经选中,当点击后就不选中
|
||||||
|
changevalue.splice(arrIndex, 1);
|
||||||
|
realValue.splice(arrIndex, 1);
|
||||||
|
} else {
|
||||||
|
// 否则选中该选项
|
||||||
|
changevalue.push(item);
|
||||||
|
realValue.push(item[props.svalue]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 触发回调函数
|
||||||
|
emit("change", changevalue, realValue);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.uni-select-dc {
|
||||||
|
position: relative;
|
||||||
|
// z-index: 999;
|
||||||
|
|
||||||
|
.uni-select-mask {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 删除按钮样式*/
|
||||||
|
.close-icon {
|
||||||
|
height: 100%;
|
||||||
|
width: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
// z-index: 3;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
text {
|
||||||
|
position: relative;
|
||||||
|
background: #c0c4cc;
|
||||||
|
width: 13px;
|
||||||
|
height: 13px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 20%;
|
||||||
|
top: 48%;
|
||||||
|
height: 1px;
|
||||||
|
width: 60%;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
background-color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//所有情空的定位
|
||||||
|
.close-postion {
|
||||||
|
position: absolute;
|
||||||
|
right: 35px;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 多选盒子 */
|
||||||
|
.uni-select-multiple {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
overflow: scroll;
|
||||||
|
|
||||||
|
.single-text {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-select-multiple-item {
|
||||||
|
background: #f4f4f5;
|
||||||
|
margin-right: 5px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #909399;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// select部分
|
||||||
|
.uni-select-dc-select {
|
||||||
|
user-select: none;
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
height: 38px;
|
||||||
|
padding: 0 30px 0 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid rgb(229, 229, 229);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
min-width: 10px;
|
||||||
|
|
||||||
|
.uni-disabled {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 19;
|
||||||
|
cursor: no-drop;
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-select-dc-input {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
display: block;
|
||||||
|
width: 96%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 30px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-select-dc-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-left: 1px solid rgb(229, 229, 229);
|
||||||
|
|
||||||
|
text {
|
||||||
|
display: block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-width: 12rpx 12rpx 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #bbb transparent transparent;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: no-drop;
|
||||||
|
|
||||||
|
text {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
border: 2px solid #ff0000;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: 0.3s;
|
||||||
|
position: relative;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
margin-top: -1px;
|
||||||
|
background-color: #ff0000;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-select-dc-inner {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
text {
|
||||||
|
display: block;
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
position: absolute;
|
||||||
|
right: 15px;
|
||||||
|
top: 8px;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
border-color: transparent transparent#bbb #bbb;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: no-drop;
|
||||||
|
|
||||||
|
text {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
border: 2px solid #ff0000;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: 0.3s;
|
||||||
|
position: relative;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
margin-top: -1px;
|
||||||
|
background-color: #ff0000;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 激活之后,图标旋转180度
|
||||||
|
&.active .uni-select-dc-icon {
|
||||||
|
text {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active .uni-select-dc-inner {
|
||||||
|
text {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 12px;
|
||||||
|
transform: rotate(-225deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// options部分
|
||||||
|
.uni-select-dc-options {
|
||||||
|
user-select: none;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 5px);
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
// height: 400rpx;
|
||||||
|
max-height: 400rpx;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid rgb(229, 229, 229);
|
||||||
|
background: #fff;
|
||||||
|
padding: 5px 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 9999;
|
||||||
|
|
||||||
|
.uni-select-dc-item {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 2.5;
|
||||||
|
transition: 0.3s;
|
||||||
|
font-size: 14px;
|
||||||
|
// 取消长按的背景色
|
||||||
|
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-focus: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #409eff;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #409eff;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
182
src/components/sliderCaptcha.vue
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<!-- 验证区域 -->
|
||||||
|
<view class="captcha-area">
|
||||||
|
<image :src="backgroundImg" class="bg-img" mode="widthFix"></image>
|
||||||
|
<view class="puzzle-hole" :style="{
|
||||||
|
left: `${holePosition.x}px`,
|
||||||
|
top: `${holePosition.y}px`,
|
||||||
|
width: `${puzzleSize.width}px`,
|
||||||
|
height: `${puzzleSize.height}px`
|
||||||
|
}"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 滑块区域 -->
|
||||||
|
<view class="slider-area">
|
||||||
|
<movable-area class="movable-area">
|
||||||
|
<movable-view class="movable-view" direction="horizontal" :x="sliderX" @change="onDrag"
|
||||||
|
@touchend="onDragEnd" :damping="40" :friction="10">
|
||||||
|
<image :src="puzzleImg" class="puzzle-img"></image>
|
||||||
|
</movable-view>
|
||||||
|
</movable-area>
|
||||||
|
<text class="slider-text">{{ sliderText }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<button class="refresh-btn" @click="initCaptcha">刷新验证码</button>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
backgroundImg: './static/images/captcha/1.jpg?v=1', // 替换为你的背景图
|
||||||
|
puzzleImg: '', // 滑块小图
|
||||||
|
holePosition: { x: 0, y: 0 }, // 缺口位置
|
||||||
|
puzzleSize: { width: 50, height: 50 }, // 滑块尺寸
|
||||||
|
sliderX: 0, // 滑块位置
|
||||||
|
targetX: 0, // 正确目标位置
|
||||||
|
isVerified: false,
|
||||||
|
sliderText: '拖动滑块完成拼图'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initCaptcha();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 初始化验证码
|
||||||
|
initCaptcha() {
|
||||||
|
this.isVerified = false;
|
||||||
|
this.sliderX = 0;
|
||||||
|
this.sliderText = '拖动滑块完成拼图';
|
||||||
|
|
||||||
|
// 随机生成缺口位置 (示例)
|
||||||
|
const maxX = 300 - this.puzzleSize.width;
|
||||||
|
const maxY = 200 - this.puzzleSize.height;
|
||||||
|
|
||||||
|
this.holePosition = {
|
||||||
|
x: Math.floor(Math.random() * maxX),
|
||||||
|
y: Math.floor(Math.random() * maxY)
|
||||||
|
};
|
||||||
|
|
||||||
|
// 这里应该从服务器获取裁剪后的小图
|
||||||
|
// 实际项目中需要通过API获取
|
||||||
|
this.puzzleImg = this.generatePuzzleImage();
|
||||||
|
|
||||||
|
// 设置目标位置 (映射到滑块轨道)
|
||||||
|
this.targetX = this.mapToSliderPosition(this.holePosition.x);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 模拟生成滑块图片 (实际应从服务端获取)
|
||||||
|
generatePuzzleImage() {
|
||||||
|
// 这里应该是从背景图裁剪的图片
|
||||||
|
return './static/images/captcha/1-1.jpg?v=1';
|
||||||
|
},
|
||||||
|
|
||||||
|
// 映射背景位置到滑块位置
|
||||||
|
mapToSliderPosition(bgX) {
|
||||||
|
const bgWidth = 300; // 背景图显示宽度
|
||||||
|
const sliderWidth = 280; // 滑块轨道宽度
|
||||||
|
return (bgX / bgWidth) * sliderWidth;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 拖动中
|
||||||
|
onDrag(e) {
|
||||||
|
if (this.isVerified) return;
|
||||||
|
this.sliderX = e.detail.x;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 拖动结束
|
||||||
|
onDragEnd() {
|
||||||
|
if (this.isVerified) return;
|
||||||
|
|
||||||
|
// 允许的误差范围
|
||||||
|
const tolerance = 5;
|
||||||
|
|
||||||
|
if (Math.abs(this.sliderX - this.targetX) < tolerance) {
|
||||||
|
this.isVerified = true;
|
||||||
|
this.sliderText = '验证成功 ✓';
|
||||||
|
uni.showToast({ title: '验证成功', icon: 'success' });
|
||||||
|
// 这里可以触发验证通过后的操作
|
||||||
|
} else {
|
||||||
|
this.sliderText = '验证失败,请重试';
|
||||||
|
this.sliderX = 0;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!this.isVerified) this.sliderText = '拖动滑块完成拼图';
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-area {
|
||||||
|
position: relative;
|
||||||
|
width: 300px;
|
||||||
|
height: 200px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.puzzle-hole {
|
||||||
|
position: absolute;
|
||||||
|
border: 2px dashed #fff;
|
||||||
|
box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.5);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-area {
|
||||||
|
width: 300px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.movable-area {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.movable-view {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.puzzle-img {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-text {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-btn {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
2
src/enums/cacheEnums.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export const TOKEN_KEY = 'token';
|
||||||
|
export const AGREEWELCOME_KEY="agreewelcome"
|
||||||
21
src/enums/requestEnums.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
export const ContentTypeEnum = {
|
||||||
|
JSON: 'application/json;charset=UTF-8'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RequestMethodsEnum = {
|
||||||
|
GET: 'GET',
|
||||||
|
POST: 'POST',
|
||||||
|
DELETE: 'DELETE',
|
||||||
|
PUT: 'PUT'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RequestCodeEnum = {
|
||||||
|
SUCCESS: 0, //成功
|
||||||
|
FAILED: -1, // 失败
|
||||||
|
TOKEN_INVALID: 10003 // TOKEN失效未登录
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RequestErrMsgEnum = {
|
||||||
|
ABORT: 'request:fail abort',
|
||||||
|
TIMEOUT: 'request:fail timeout'
|
||||||
|
};
|
||||||
19
src/main.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { createSSRApp } from "vue";
|
||||||
|
import App from "./App.vue";
|
||||||
|
|
||||||
|
import '@/static/font/iconfont.css'
|
||||||
|
|
||||||
|
// pinia
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
|
const pinia = createPinia()
|
||||||
|
|
||||||
|
export function createApp() {
|
||||||
|
|
||||||
|
const app = createSSRApp(App);
|
||||||
|
|
||||||
|
app.use(pinia)
|
||||||
|
|
||||||
|
return {
|
||||||
|
app,
|
||||||
|
};
|
||||||
|
}
|
||||||
91
src/manifest.json
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
{
|
||||||
|
"id" : "H5E705637",
|
||||||
|
"name" : "app",
|
||||||
|
// "appid" : "",
|
||||||
|
"description" : "",
|
||||||
|
"versionName" : "1.0.0",
|
||||||
|
"versionCode" : "100",
|
||||||
|
"transformPx" : false,
|
||||||
|
/* 5+App特有相关 */
|
||||||
|
"app-plus" : {
|
||||||
|
"compatible" : {
|
||||||
|
"ignoreVersion" : true //true表示忽略版本检查 提示框HBuilderx1.9.0及
|
||||||
|
},
|
||||||
|
"usingComponents" : true,
|
||||||
|
"nvueStyleCompiler" : "uni-app",
|
||||||
|
"compilerVersion" : 3,
|
||||||
|
"splashscreen" : {
|
||||||
|
"alwaysShowBeforeRender" : true,
|
||||||
|
"waiting" : true,
|
||||||
|
"autoclose" : true,
|
||||||
|
"delay" : 0
|
||||||
|
},
|
||||||
|
/* 模块配置 */
|
||||||
|
"modules" : {},
|
||||||
|
/* 应用发布信息 */
|
||||||
|
"distribute" : {
|
||||||
|
/* android打包配置 */
|
||||||
|
"android" : {
|
||||||
|
"permissions" : [
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||||
|
],
|
||||||
|
"icons" : {
|
||||||
|
"android" : {
|
||||||
|
"hdpi" : "static/icons/72x72.png",
|
||||||
|
"xhdpi" : "static/icons/96x96.png",
|
||||||
|
"xxhdpi" : "static/icons/144x144.png",
|
||||||
|
"xxxhdpi" : "static/icons/192x192.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* ios打包配置 */
|
||||||
|
"ios" : {},
|
||||||
|
/* SDK配置 */
|
||||||
|
"sdkConfigs" : {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false
|
||||||
|
},
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "3",
|
||||||
|
"h5" : {
|
||||||
|
"router" : {
|
||||||
|
"base" : ""
|
||||||
|
/*,"mode": "history" 仅对 H5 平台生效 */
|
||||||
|
},
|
||||||
|
"template" : "index.html"
|
||||||
|
}
|
||||||
|
}
|
||||||
146
src/pages.json
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"easycom": {
|
||||||
|
"autoscan": true,
|
||||||
|
"custom": {
|
||||||
|
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "pages/loading/loading",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/login/login",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/home/home",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/business",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/visitorReport",//市场信息管理
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/visitorReportAdd",//走访报告添加
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/visitorReportDetail",//走访报告详情
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/visitorReportEnter",//走访报告内容录入
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/marketInformation",//市场信息管理
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/weekPlanUpdate",//修改周计划
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/vistorCheckin",//签到打卡
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/checkinStatistics",//打卡统计
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/paymentCollection",//回款查看
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/notice/notice",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "",
|
||||||
|
"app-plus" : {
|
||||||
|
"bounce" : "none" // 取消APP端iOS回弹,避免与下拉刷新冲突 (可统一配在 'globalStyle')
|
||||||
|
},
|
||||||
|
"mp-alipay":{"allowsBounceVertical":"NO"} // 取消支付宝和钉钉小程序的iOS回弹,避免与下拉刷新冲突 (可统一配在 'globalStyle')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/userinfo/userinfo",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "718友晟",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#F8F8F8",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
},
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#919191",
|
||||||
|
"selectedColor": "#ffffff",
|
||||||
|
"borderStyle": "#ffffff",
|
||||||
|
"backgroundColor": "#000000",
|
||||||
|
"fontSize": "12px",
|
||||||
|
"iconWidth": "24px",
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"pagePath": "pages/home/home",
|
||||||
|
"iconPath": "static/images/tabs/menu-home.png",
|
||||||
|
"selectedIconPath": "static/images/tabs/menu-home-on.png",
|
||||||
|
"text": "首页"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/business/business",
|
||||||
|
"iconPath": "static/images/tabs/menu-business.png",
|
||||||
|
"selectedIconPath": "static/images/tabs/menu-business-on.png",
|
||||||
|
"text": "业务中心"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/notice/notice",
|
||||||
|
"iconPath": "static/images/tabs/menu-info.png",
|
||||||
|
"selectedIconPath": "static/images/tabs/menu-info-on.png",
|
||||||
|
"text": "消息"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/userinfo/userinfo",
|
||||||
|
"iconPath": "static/images/tabs/menu-me.png",
|
||||||
|
"selectedIconPath": "static/images/tabs/menu-me-on.png",
|
||||||
|
"text": "我的"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
234
src/pages/business/CRM/checkinStatistics.vue
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'打卡统计'" :leftFlag="true" :rightFlag="false"></customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<view>
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<view class="search">
|
||||||
|
<picker @change="bindPickerChange" :value="cityIndex" :range="cityArr" class="picker-bg">
|
||||||
|
<view class="picker">
|
||||||
|
<uni-icons type="location" size="18"></uni-icons>
|
||||||
|
<view>{{cityArr[cityIndex]}}</view>
|
||||||
|
<uni-icons type="down" size="18"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
<picker mode="date" :value="defaultDate" :start="startDate" :end="endDate"
|
||||||
|
@change="bindDateChange" class="picker-bg">
|
||||||
|
<view class="picker">
|
||||||
|
<uni-icons custom-prefix="iconfont" color="#ffffff" type="icon-phoneshizhong" size="18"></uni-icons>
|
||||||
|
<view>{{defaultDate}}</view>
|
||||||
|
<uni-icons type="down" size="18"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
<button type="default" @click="handleSearch" size="mini" class="btn-search">查询</button>
|
||||||
|
</view>
|
||||||
|
<!-- 签到打卡 -->
|
||||||
|
<view class="checkin-tab">
|
||||||
|
<view class="checkin-tab-item" :class="{active:tabType==0}" @click="handleTab(0)">
|
||||||
|
<view class="tab-item-title">7</view>
|
||||||
|
<view class="tab-item-name">最新签到打卡</view>
|
||||||
|
</view>
|
||||||
|
<view class="checkin-tab-item" :class="{active:tabType==1}" @click="handleTab(1)">
|
||||||
|
<view class="tab-item-title">4</view>
|
||||||
|
<view class="tab-item-name">未签到打卡</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- tab切换显示 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<!-- 最新签到列表 -->
|
||||||
|
<view class="tab-con" v-if="tabType==0">
|
||||||
|
<view class="tab-title" v-for="(item,index) in list1" :key="index">
|
||||||
|
{{item}}
|
||||||
|
<uni-icons type="checkbox-filled" size="26" color="#02C74C"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 未签到列表 -->
|
||||||
|
<view class="tab-con" v-if="tabType==1">
|
||||||
|
<view class="tab-title" v-for="(item,index) in list2" :key="index">
|
||||||
|
{{item}}
|
||||||
|
<uni-icons type="info-filled" size="26" color="#FF8059"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import { getDate} from '@/utils/datetime.js'
|
||||||
|
|
||||||
|
let cityIndex = ref(0);
|
||||||
|
let cityArr = ["北京大区","天津大区"];
|
||||||
|
// 选择大区列表
|
||||||
|
let bindPickerChange = (e)=>{
|
||||||
|
console.log('picker发送选择改变,携带值为', e.detail.value)
|
||||||
|
cityIndex.value = e.detail.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始时间
|
||||||
|
let startDate = getDate('start');
|
||||||
|
// 结束时间,间隔10年
|
||||||
|
let endDate = getDate('end');
|
||||||
|
let defaultDate = getDate({ format: true })
|
||||||
|
let bindDateChange = (e) =>{
|
||||||
|
defaultDate = e.detail.value
|
||||||
|
}
|
||||||
|
|
||||||
|
let searchValue = ref(null)
|
||||||
|
// 查询搜索跳转
|
||||||
|
let handleSearch = () => {
|
||||||
|
console.log(searchValue.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// tab 切换
|
||||||
|
let tabType = ref(0)
|
||||||
|
let handleTab = (type)=>{
|
||||||
|
tabType.value = type;
|
||||||
|
}
|
||||||
|
// 列表
|
||||||
|
let list1 = ref([]);
|
||||||
|
list1.value = ["王振","胡本华","高勐","崔礼涛","汪津春","王永健","张浩"];
|
||||||
|
|
||||||
|
let list2 = ref([]);
|
||||||
|
list2.value = ["付翰","张旭光","赵欣鸣","张王小北"];
|
||||||
|
|
||||||
|
// 确定
|
||||||
|
let handleSubmit = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
padding:0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
line-height: normal;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 56rpx !important;
|
||||||
|
padding: 10rpx 0 0;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.search .picker-bg{
|
||||||
|
display: flex;
|
||||||
|
background-color: #6FA2F8;
|
||||||
|
border-radius: 25px;
|
||||||
|
color:#fff;
|
||||||
|
font-size:28rpx;
|
||||||
|
padding:0rpx 20rpx;
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
padding:10rpx 20rpx 0 20rpx;
|
||||||
|
/* #endif */
|
||||||
|
margin-right:20rpx;
|
||||||
|
}
|
||||||
|
.search .picker-bg .picker {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
padding-top:2rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.search .picker-bg .picker .uni-icons{
|
||||||
|
color:#fff !important;
|
||||||
|
}
|
||||||
|
.search .picker-bg .picker .uni-icons:first-child{
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
.search .picker-bg .picker .uniui-down{
|
||||||
|
margin-left: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkin-tab{
|
||||||
|
margin-top:35rpx;
|
||||||
|
display: flex;
|
||||||
|
padding:0 30rpx;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.checkin-tab-item{
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color:rgba(255, 255, 255, 0.5);
|
||||||
|
text-align: center;
|
||||||
|
margin-right:30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-bottom:20rpx;
|
||||||
|
}
|
||||||
|
.checkin-tab-item.active{
|
||||||
|
position: relative;
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
.checkin-tab-item.active::after{
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100rpx;
|
||||||
|
height: 8rpx;
|
||||||
|
}
|
||||||
|
.checkin-tab-item .tab-item-title{
|
||||||
|
font-size:60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
width: 670rpx;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
padding:50rpx 40rpx;
|
||||||
|
margin-top:20rpx;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:calc(100vh - 260px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height:calc(100vh - 230px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-con{
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap
|
||||||
|
}
|
||||||
|
.tab-con .tab-title{
|
||||||
|
border:1px solid #E8E8E8;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
position: relative;
|
||||||
|
/* padding:10rpx 20rpx; */
|
||||||
|
margin-right:20rpx;
|
||||||
|
margin-bottom:30rpx;
|
||||||
|
width:148rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
.tab-con .tab-title:nth-child(4n){
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.tab-con .uni-icons{
|
||||||
|
position: absolute;
|
||||||
|
right:-10px;
|
||||||
|
top:-10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
224
src/pages/business/CRM/marketInformation.vue
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'市场信息管理'" :leftFlag="true" :rightFlag="true">
|
||||||
|
<template #right>
|
||||||
|
<view class="head-right" @click="handleAdd">
|
||||||
|
<uni-icons type="plus" size="24" color="#B7D2FF"></uni-icons>新增
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height" :style="{ paddingTop: navBarPaddingTop + 'px' }"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<view class="all-body market-con">
|
||||||
|
<view class="nav-list">
|
||||||
|
<view class="nav-item" :class="{active:index==activeTab}"
|
||||||
|
v-for="(item,index) in tabList" :key="index"
|
||||||
|
@click="handleNav(index)"
|
||||||
|
>{{ item }}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 分页部分 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
|
||||||
|
:up="upOption" :down="downOption" :fixed="false" textColor="#ffffff" bgColor="#ffffff"
|
||||||
|
class="scroll-h" :class="{'loading-scroll':cssFlag}">
|
||||||
|
<!-- 市场机会信息 -->
|
||||||
|
<block v-if="activeTab === 0">
|
||||||
|
市场机会信息内容
|
||||||
|
</block>
|
||||||
|
<!-- 重大事项信息 -->
|
||||||
|
<block v-if="activeTab === 1">
|
||||||
|
<view class="white-bg margin-bottom20" v-for="(item, index) in list" :key="index">
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="title r-list">
|
||||||
|
<view class="r-left" style="font-size:38rpx;">{{ item.title }}</view>
|
||||||
|
<view class="r-right btn-gray flex-auto" :class="{'btn-blue':item.status==2}" size="mini">{{ item.statusName }}</view>
|
||||||
|
</view>
|
||||||
|
<view style="padding:0rpx 0 10rpx">
|
||||||
|
<view class="font-bold" style="padding-bottom:10rpx">产生影响</view>
|
||||||
|
<view class="font-gray">{{ item.desc }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import { getNavBarPaddingTop } from '@/utils/system.js'
|
||||||
|
import { mattersList } from '@/api/business.js'
|
||||||
|
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
})
|
||||||
|
|
||||||
|
const activeTab = ref(1);// 默认重大事项信息
|
||||||
|
const tabList = ['市场机会信息', '重大事项信息', '竞争对手信息', '人员变动信息','多标签效果','多标签效果'];
|
||||||
|
let handleNav = (index)=>{
|
||||||
|
console.log(index)
|
||||||
|
activeTab.value = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
let handleAdd = () => {
|
||||||
|
// uni.navigateTo({ url: '/pages/business/CRM/visitorReportAdd' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询列表
|
||||||
|
let list = ref([]);
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const upOption = ref({
|
||||||
|
page: { num: 0, size: 10 },
|
||||||
|
noMoreSize: 5,
|
||||||
|
empty: { tip: '~ 空空如也 ~' },
|
||||||
|
textLoading: '加载中...',
|
||||||
|
textNoMore: '已经到底了'
|
||||||
|
});
|
||||||
|
|
||||||
|
const downOption = ref({
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
let cssFlag=ref(false);//控制样式
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
cssFlag.value = true;
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const res = await getMattersList(1, upOption.value.page.size);
|
||||||
|
cssFlag.value = false;
|
||||||
|
list.value = res.list;
|
||||||
|
mescroll.resetUpScroll();
|
||||||
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async () => {
|
||||||
|
mescroll.endSuccess();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上拉加载更多
|
||||||
|
const upCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const res = await getMattersList(mescroll.num, mescroll.size);
|
||||||
|
if (mescroll.num === 1) {
|
||||||
|
list.value = res.list;
|
||||||
|
} else {
|
||||||
|
list.value.push(...res.list);
|
||||||
|
}
|
||||||
|
mescroll.endBySize(res.list.length, res.total);
|
||||||
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getMattersList = (pageIndex, pageSize) => {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
let param = {
|
||||||
|
pageIndex,
|
||||||
|
pageSize
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = await mattersList(param);
|
||||||
|
resolve({
|
||||||
|
list: res.list,
|
||||||
|
total: res.totalCount
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.all-body{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
top:88rpx;
|
||||||
|
height: calc(100vh - 44px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
top:100rpx;
|
||||||
|
height: calc(100vh - 48px);
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
}
|
||||||
|
/*.market-con{
|
||||||
|
|
||||||
|
} */
|
||||||
|
|
||||||
|
.nav-list{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
padding:80rpx 30rpx 0;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
padding:20rpx 30rpx 0;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.nav-list .nav-item{
|
||||||
|
background-color:#05A3F4;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
color:#FFFFFF;
|
||||||
|
font-size:28rpx;
|
||||||
|
text-align: center;
|
||||||
|
padding:10rpx 25rpx;
|
||||||
|
margin-right:15rpx;
|
||||||
|
margin-bottom:20rpx;
|
||||||
|
}
|
||||||
|
.nav-list .nav-item:nth-child(3n){
|
||||||
|
margin-right:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-list .nav-item.active{
|
||||||
|
background-color: #fff;
|
||||||
|
color:#3384DF;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list{
|
||||||
|
align-items:flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.scroll-h {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 155px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 135px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
padding-top:10rpx;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
.report-list .title{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
169
src/pages/business/CRM/paymentCollection.vue
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'个人回款信息统计表'" :leftFlag="true" :rightFlag="false"></customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<view>
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<view class="search">
|
||||||
|
<picker mode="date" :value="defaultDate" :start="startDate" :end="endDate"
|
||||||
|
@change="bindDateChange" class="picker-bg">
|
||||||
|
<view class="picker">
|
||||||
|
<uni-icons custom-prefix="iconfont" color="#ffffff" type="icon-phoneshizhong" size="18"></uni-icons>
|
||||||
|
<view>{{defaultDate}}</view>
|
||||||
|
<uni-icons type="down" size="18"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
<picker @change="bindPickerChange" :value="peopleIndex" :range="peopleArr" class="picker-bg">
|
||||||
|
<view class="picker">
|
||||||
|
<uni-icons type="person" size="18"></uni-icons>
|
||||||
|
<view>{{peopleArr[peopleIndex]}}</view>
|
||||||
|
<uni-icons type="down" size="18"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
<button type="default" @click="handleSearch" size="mini" class="btn-search">查询</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 回款信息查询 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="table-title">回款信息查询</view>
|
||||||
|
<table class="my-table">
|
||||||
|
<tr>
|
||||||
|
<th class="tab-width100">姓名</th>
|
||||||
|
<th class="tab-width160">客户名称</th>
|
||||||
|
<th>目标回款</th>
|
||||||
|
<th>实际回款</th>
|
||||||
|
<th>完成度</th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="(item, index) in tableData" :key="index">
|
||||||
|
<td>{{ item.name }}</td>
|
||||||
|
<td class="txtLeft">{{ item.guestName }}</td>
|
||||||
|
<td>{{ item.tragetReturnMoney }}</td>
|
||||||
|
<td>{{ item.returnMoney }}</td>
|
||||||
|
<td>{{ item.completRate }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import { getDate} from '@/utils/datetime.js'
|
||||||
|
|
||||||
|
|
||||||
|
// 开始时间
|
||||||
|
let startDate = getDate('start');
|
||||||
|
// 结束时间,间隔10年
|
||||||
|
let endDate = getDate('end');
|
||||||
|
let defaultDate = getDate({ format: true })
|
||||||
|
let bindDateChange = (e) =>{
|
||||||
|
defaultDate = e.detail.value
|
||||||
|
}
|
||||||
|
|
||||||
|
let peopleIndex = ref(0);
|
||||||
|
let peopleArr = ["张志刚1","张志刚2"];
|
||||||
|
// 选择列表
|
||||||
|
let bindPickerChange = (e)=>{
|
||||||
|
console.log('picker发送选择改变,携带值为', e.detail.value)
|
||||||
|
peopleIndex.value = e.detail.value
|
||||||
|
}
|
||||||
|
|
||||||
|
let searchValue = ref(null)
|
||||||
|
// 查询搜索跳转
|
||||||
|
let handleSearch = () => {
|
||||||
|
console.log(searchValue.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableData = [
|
||||||
|
{ name: '张志钢',guestName:'航宇救生装备有限公司',tragetReturnMoney:677153.25,returnMoney:677153.25,completRate:'100%'},
|
||||||
|
{ name: '张志钢',guestName:'中国船舶集团有限公司第七一七研究所',tragetReturnMoney:'700000.00',returnMoney:'53890.00',completRate:'7.7%'},
|
||||||
|
{ name: '张志钢',guestName:'北京国科舰航传感技术有限公司',tragetReturnMoney:'290877.00',returnMoney:'290877.00',completRate:'100%'},
|
||||||
|
{ name: '张志钢',guestName:'武汉杭久电气有限公司',tragetReturnMoney:869706.80,returnMoney:537809.75,completRate:'61.8%'},
|
||||||
|
{ name: '张志钢',guestName:'深圳市欧灿科技有限公司',tragetReturnMoney:328097.10,returnMoney:297905.37,completRate:'90.8%'},
|
||||||
|
{ name: '张志钢',guestName:'其他',tragetReturnMoney:558703.02,returnMoney:558703.02,completRate:'100%'},
|
||||||
|
{ name: '张志钢',guestName:'武汉航空仪表有限责任公司',tragetReturnMoney:'9807328.00',returnMoney:8692300.93,completRate:'88.6%'},
|
||||||
|
{ name: '张志钢',guestName:'武汉永力科技股份有限公司',tragetReturnMoney:539087.21,returnMoney:539087.21,completRate:'100%'},
|
||||||
|
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
padding:0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
line-height: normal;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 56rpx !important;
|
||||||
|
padding: 10rpx 0 0;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.search .picker-bg{
|
||||||
|
display: flex;
|
||||||
|
background-color: #6FA2F8;
|
||||||
|
border-radius: 25px;
|
||||||
|
color:#fff;
|
||||||
|
font-size:28rpx;
|
||||||
|
padding:0rpx 20rpx;
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
padding:10rpx 20rpx 0 20rpx;
|
||||||
|
/* #endif */
|
||||||
|
margin-right:20rpx;
|
||||||
|
}
|
||||||
|
.search .picker-bg .picker {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
padding-top:2rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.search .picker-bg .picker .uni-icons{
|
||||||
|
color:#fff !important;
|
||||||
|
}
|
||||||
|
.search .picker-bg .picker .uni-icons:first-child{
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
.search .picker-bg .picker .uniui-down{
|
||||||
|
margin-left: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
width: 750rpx;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
padding:20rpx 0rpx;
|
||||||
|
margin-top:20rpx;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:calc(100vh - 135px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height:calc(100vh - 112px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-title{
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom:2px solid #E7E7E7;
|
||||||
|
padding-bottom:20rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
216
src/pages/business/CRM/visitorReport.vue
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'走访报告列表'" :leftFlag="true" :rightFlag="true">
|
||||||
|
<template #right>
|
||||||
|
<view class="head-right" @click="handleAdd">
|
||||||
|
<uni-icons type="plus" size="24" color="#B7D2FF"></uni-icons>新增
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height" :style="{ paddingTop: navBarPaddingTop + 'px' }"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<view class="all-body">
|
||||||
|
<!-- 搜索 @blur="blur" @focus="focus" @input="input" @cancel="cancel" @clear="clear"-->
|
||||||
|
<view class="search">
|
||||||
|
<uni-search-bar class="custom-search" radius="28" placeholder="请输入客户名称" clearButton="auto"
|
||||||
|
cancelButton="none" bgColor="#6FA2F8" textColor="#ffffff"
|
||||||
|
v-model="searchValue"
|
||||||
|
/>
|
||||||
|
<button type="default" @click="handleSearch" size="mini" class="btn-search">查询</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 分页部分 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
|
||||||
|
:up="upOption" :down="downOption" :fixed="false" textColor="#ffffff" bgColor="#ffffff"
|
||||||
|
class="scroll-h" :class="{'loading-scroll':cssFlag}"
|
||||||
|
>
|
||||||
|
<view class="white-bg margin-bottom20" v-for="(item, index) in list" :key="index" @click="handleDetail(item)">
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="title">{{ item.title }}</view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-name">{{ item.name }}</view>
|
||||||
|
<view class="r-right btn-orange" size="mini">{{ item.statusName }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">报告类型</view>
|
||||||
|
<view class="r-right">{{ item.reportTypeName }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">报告人</view>
|
||||||
|
<view class="r-right">{{ item.reportPeople }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">报告日期</view>
|
||||||
|
<view class="r-right">{{ item.dateStr }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import { getNavBarPaddingTop } from '@/utils/system.js'
|
||||||
|
import { visitorReportList } from '@/api/business.js'
|
||||||
|
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
})
|
||||||
|
|
||||||
|
let searchValue = ref(null)
|
||||||
|
// 查询搜索跳转
|
||||||
|
let handleSearch = () => {
|
||||||
|
console.log(searchValue.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
let handleAdd = ()=>{
|
||||||
|
uni.navigateTo({ url:'/pages/business/CRM/visitorReportAdd' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询列表
|
||||||
|
let list = ref([]);
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const upOption = ref({
|
||||||
|
page: { num: 0, size: 10 },
|
||||||
|
noMoreSize: 5,
|
||||||
|
empty: { tip: '~ 空空如也 ~' },
|
||||||
|
textLoading: '加载中...',
|
||||||
|
textNoMore: '已经到底了'
|
||||||
|
});
|
||||||
|
|
||||||
|
const downOption = ref({
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
let cssFlag=ref(false);//控制样式
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
cssFlag.value = true;
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
const res = await getVisitorReportList(1, upOption.value.page.size);
|
||||||
|
cssFlag.value = false;
|
||||||
|
list.value = res.list;
|
||||||
|
mescroll.resetUpScroll();
|
||||||
|
},500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
mescroll.endSuccess();
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上拉加载更多
|
||||||
|
const upCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
const res = await getVisitorReportList(mescroll.num, mescroll.size);
|
||||||
|
if (mescroll.num === 1) {
|
||||||
|
list.value = res.list;
|
||||||
|
} else {
|
||||||
|
list.value.push(...res.list);
|
||||||
|
}
|
||||||
|
mescroll.endBySize(res.list.length, res.total);
|
||||||
|
},500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getVisitorReportList = (pageIndex, pageSize) => {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
let param = {
|
||||||
|
pageIndex,
|
||||||
|
pageSize
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = await visitorReportList(param);
|
||||||
|
resolve({
|
||||||
|
list: res.list,
|
||||||
|
total: res.totalCount
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到详情
|
||||||
|
let handleDetail=(item)=>{
|
||||||
|
uni.navigateTo({
|
||||||
|
url: "/pages/business/CRM/visitorReportDetail?id="+item.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.all-body {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
top: 150rpx;
|
||||||
|
height: calc(100vh - 75px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
top:120rpx;
|
||||||
|
height: calc(100vh);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.search{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.search .btn-search{
|
||||||
|
border:none;
|
||||||
|
background: none;
|
||||||
|
line-height: normal;
|
||||||
|
color:#fff;
|
||||||
|
line-height: 56rpx !important;
|
||||||
|
padding:10rpx 0 0;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.search .btn-search::after{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.search .custom-search{
|
||||||
|
width:80%;
|
||||||
|
|
||||||
|
}
|
||||||
|
.search .custom-search.uni-searchbar{
|
||||||
|
padding-right:0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 120px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 110px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.white-bg{
|
||||||
|
padding-bottom:10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
150
src/pages/business/CRM/visitorReportAdd.vue
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'走访报告添加'" :leftFlag="true" :rightFlag="true">
|
||||||
|
<template #right>
|
||||||
|
<view class="head-right" @click="submitForm">
|
||||||
|
<uni-icons custom-prefix="iconfont" type="icon-phonebaocun" size="22"
|
||||||
|
color="#B7D2FF"></uni-icons>保存
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="form-con">
|
||||||
|
<uni-forms ref="formRef" :model="formData" :rules="rules" label-width="100px" >
|
||||||
|
<uni-forms-item label="客户名称" name="guestName" class="f-c-right">
|
||||||
|
<picker @change="bindPickerChange" :value="guestIndex" :range="guestArr">
|
||||||
|
<view class="f-c-text">
|
||||||
|
{{guestArr[guestIndex]}}
|
||||||
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="签到记录" class="f-c-right">
|
||||||
|
<view class="f-c-text txt-right">--</view>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="我方领导" name="leader" required class="uni-forms-item is-direction-top is-top">
|
||||||
|
<uni-easyinput v-model="formData.leader" placeholder="请输入我方领导" />
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="走访日期" name="visitDate" class="uni-forms-item is-direction-top is-top">
|
||||||
|
<uni-datetime-picker type="date" :clear-icon="false" v-model="formData.visitDate" @change="changeDate" />
|
||||||
|
</uni-forms-item>
|
||||||
|
</uni-forms>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import{ getGuestList} from '@/api/business.js'
|
||||||
|
|
||||||
|
// 客户名称列表
|
||||||
|
let guestList = ref([]);
|
||||||
|
let guestArr = ref([])
|
||||||
|
let guestIndex = ref(0);
|
||||||
|
let selectGuestList = async ()=>{
|
||||||
|
let res = await getGuestList();
|
||||||
|
let list = res.list;
|
||||||
|
list.forEach(item => {
|
||||||
|
guestArr.value.push(item.name)
|
||||||
|
});
|
||||||
|
guestList.value = res.list
|
||||||
|
}
|
||||||
|
selectGuestList();
|
||||||
|
|
||||||
|
// 选择客户列表
|
||||||
|
let bindPickerChange = (e)=>{
|
||||||
|
console.log('picker发送选择改变,携带值为', e.detail.value)
|
||||||
|
guestIndex.value = e.detail.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单ref
|
||||||
|
const formRef = ref(null);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref({
|
||||||
|
guestName:'',
|
||||||
|
leader:'',
|
||||||
|
visitDate:''
|
||||||
|
});
|
||||||
|
// 验证规则
|
||||||
|
const rules = {
|
||||||
|
leader: {
|
||||||
|
rules: [
|
||||||
|
{ required: true, errorMessage: '我方领导不能为空' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改日期
|
||||||
|
let changeDate = (e)=>{
|
||||||
|
console.log('changeDate:', e);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存走访报告
|
||||||
|
const submitForm = async () => {
|
||||||
|
try {
|
||||||
|
// 验证表单
|
||||||
|
await formRef.value.validate();
|
||||||
|
|
||||||
|
// 验证通过后的操作
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证通过',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
console.log('表单数据:', formData.value);
|
||||||
|
|
||||||
|
// 这里可以添加提交到服务器的代码
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log('表单验证失败:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.white-bg {
|
||||||
|
width: 750rpx;
|
||||||
|
padding: 30rpx 0 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
.form-con{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:calc(100vh - 100px)
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height:calc(100vh - 80px)
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.uni-date-x){
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
:deep(.uni-date-x .icon-calendar){
|
||||||
|
float: right;
|
||||||
|
margin-top:15rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
background:url('../../../static/images/business/icon-date.png') no-repeat;
|
||||||
|
background-size:32rpx 35rpx;
|
||||||
|
width:32rpx;
|
||||||
|
height: 35rpx;
|
||||||
|
}
|
||||||
|
:deep(.uni-date-x .icon-calendar::before){
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
:deep(.uni-date-x .uni-date__x-input){
|
||||||
|
padding-left:20rpx;
|
||||||
|
color:#919191;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
190
src/pages/business/CRM/visitorReportDetail.vue
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'走访报告详情'" :leftFlag="true" :rightFlag="false"></customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<!-- 详情内容 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="title">{{ item.title }}</view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-name">{{ item.name }}</view>
|
||||||
|
<view class="r-right btn-pink" size="mini" @click="handleZan">
|
||||||
|
<uni-icons type="hand-up-filled" size="16" color="#ffffff"></uni-icons> 赞
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">报告人</view>
|
||||||
|
<view class="r-right">{{ item.reportPeople }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">走访日期</view>
|
||||||
|
<view class="r-right">{{ item.dateStr }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">是否双方高层领导参与</view>
|
||||||
|
<view class="r-right">{{ item.isJoin }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">活动类型</view>
|
||||||
|
<view class="r-right">{{ item.activityTypeName }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 报告明细&评论 -->
|
||||||
|
<customTabs v-model="activeTab" :tabs="tabList" :modelValue="activeTab">
|
||||||
|
<!-- 报告明细 -->
|
||||||
|
<block v-if="activeTab === 0">
|
||||||
|
<view class="white-bg white-bg-2">
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">拜访事项</view>
|
||||||
|
<view class="r-right">获得信息</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">拜访类型</view>
|
||||||
|
<view class="r-right">竞争对手信息</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list" style="display: block">
|
||||||
|
<view class="r-name">结果</view>
|
||||||
|
<view class="r-gray">考察了几家连接器单位,陶瓷管壳55所、43所现在的开模费有所下降,便宜的几千块钱。</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="white-bg white-bg-2">
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">拜访事项</view>
|
||||||
|
<view class="r-right">日常走访</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">拜访类型</view>
|
||||||
|
<view class="r-right">竞争对手信息</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">客户人员</view>
|
||||||
|
<view class="r-right">孙琳琳、顾鹏、田玲</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">我方人员</view>
|
||||||
|
<view class="r-right">肖建华、石宪、刘启运、赵震</view>
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom b-width"></view>
|
||||||
|
<view class="r-list" style="display: block">
|
||||||
|
<view class="r-name">结果</view>
|
||||||
|
<view class="r-gray">
|
||||||
|
<view class="margin-bottom20" >1、江苏屹信现在有意向寻找第二家管壳供方,主要是因为客户要求做一些封装产品和自研顶目涉及到SIP系统级封装研发工作。 </view>
|
||||||
|
<view>2、江苏屹信管壳主要是功放管壳带热沉/CPC/钨铜/钼铜。陶瓷管壳希望在30天内交付。</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<!-- 评论 -->
|
||||||
|
<block v-if="activeTab === 1">
|
||||||
|
<view class="white-bg white-bg-2">评论内容</view>
|
||||||
|
</block>
|
||||||
|
</customTabs>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 底部加高度来避免tabbar遮挡 -->
|
||||||
|
<view class="bottom-height"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import customTabs from '@/components/customTabs.vue';
|
||||||
|
import { visitorReportDetail } from '@/api/business.js'
|
||||||
|
|
||||||
|
|
||||||
|
// 加载后调用
|
||||||
|
let id = ref(null)
|
||||||
|
onLoad((options) => {
|
||||||
|
id.value = options.id;
|
||||||
|
getVisitorReportDetail();
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查询详情
|
||||||
|
let item = ref({});
|
||||||
|
const getVisitorReportDetail = async () => {
|
||||||
|
let param = {
|
||||||
|
id: id.value
|
||||||
|
}
|
||||||
|
let res = await visitorReportDetail(param);
|
||||||
|
item.value = res.activeObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 报告明细&评论
|
||||||
|
const activeTab = ref(0);//默认报告明细
|
||||||
|
const tabList = ['报告明细', '评论'];
|
||||||
|
|
||||||
|
// 跳转走访报告录入
|
||||||
|
let handleZan = ()=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.white-bg {
|
||||||
|
width: 690rpx;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
.white-bg.white-bg-2{
|
||||||
|
border-radius:0;
|
||||||
|
margin-bottom:20rpx;
|
||||||
|
}
|
||||||
|
:deep(.tabs-header) {
|
||||||
|
/* background: none !important; */
|
||||||
|
border-bottom: none !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
:deep(.tab-item) {
|
||||||
|
color:#919191;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
/* flex:none; */
|
||||||
|
/* margin: 0 -50rpx; */
|
||||||
|
/* padding: 0 50rpx; */
|
||||||
|
}
|
||||||
|
:deep(.tab-item:first-child){
|
||||||
|
text-align: right;
|
||||||
|
margin-left:230rpx;
|
||||||
|
}
|
||||||
|
:deep(.tab-item:last-child){
|
||||||
|
text-align: left;
|
||||||
|
margin-right:230rpx;
|
||||||
|
}
|
||||||
|
:deep(.tab-item.active) {
|
||||||
|
color: #3384DF;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
:deep(.tab-item.active::after) {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
215
src/pages/business/CRM/visitorReportEnter.vue
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'走访报告内容录入'" :leftFlag="true" :rightFlag="false"></customHeader>
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 日常走访 -->
|
||||||
|
<view class="white-bg white-bg-2">
|
||||||
|
<view class="w-b-title" @click="handleExpand">日常走访
|
||||||
|
<text>
|
||||||
|
{{ expandFlag ? '展开' : '收起' }}
|
||||||
|
<i :class="{ iconfont: true, 'icon-up': !expandFlag, 'icon-down': expandFlag }"></i>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="!expandFlag" class="form-con">
|
||||||
|
<uni-forms ref="formRef" :model="formData" :rules="rules" label-width="100px" label-position="top">
|
||||||
|
<uni-forms-item label="客户人员" name="guestName1" class="f-c-right">
|
||||||
|
<multipleSelect :multiple="true" :value="monIndex1" downInner :options="guestList1"
|
||||||
|
@change="changeValue1" :key="Math.round()"
|
||||||
|
></multipleSelect>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="我方参与人" name="guestName2" class="f-c-right">
|
||||||
|
<multipleSelect :multiple="true" :value="monIndex2" downInner :options="guestList2"
|
||||||
|
@change="changeValue2" :key="Math.round()"
|
||||||
|
></multipleSelect>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="活动内容" name="activeCon" required
|
||||||
|
class="uni-forms-item is-direction-top is-top">
|
||||||
|
<multipleSelect :multiple="true" :value="monIndex3" downInner :options="guestList3"
|
||||||
|
@change="changeValue3" :key="Math.round()"
|
||||||
|
></multipleSelect>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="活动文字" name="activeTxt" class="uni-forms-item is-direction-top is-top">
|
||||||
|
<uni-easyinput type="textarea" autoHeight v-model="formData.activeTxt" placeholder="请输入" class="form-texarea" />
|
||||||
|
</uni-forms-item>
|
||||||
|
</uni-forms>
|
||||||
|
<view class="footer-con">
|
||||||
|
<button class="btn-default" type="default" @click="handleDelete" size="mini">删 除</button>
|
||||||
|
<button class="btn-primary" type="primary" @click="submitForm" size="mini">保存/修改</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 业务招待 -->
|
||||||
|
<view class="white-bg white-bg-2 white-bg-3">
|
||||||
|
<view class="w-b-title" @click="handleExpand2">业务招待
|
||||||
|
<text>
|
||||||
|
{{ expandFlag2 ? '展开' : '收起' }}
|
||||||
|
<i :class="{ iconfont: true, 'icon-up': !expandFlag2, 'icon-down': expandFlag2 }"></i>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="!expandFlag2" class="form-con">
|
||||||
|
业务招待
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 技术交流 -->
|
||||||
|
<view class="white-bg white-bg-2 white-bg-3">
|
||||||
|
<view class="w-b-title" @click="handleExpand3">技术交流
|
||||||
|
<text>
|
||||||
|
{{ expandFlag3 ? '展开' : '收起' }}
|
||||||
|
<i :class="{ iconfont: true, 'icon-up': !expandFlag3, 'icon-down': expandFlag3 }"></i>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="!expandFlag3" class="form-con">
|
||||||
|
技术交流
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import multipleSelect from '@/components/multipleSelect.vue'
|
||||||
|
|
||||||
|
|
||||||
|
// 日常走访
|
||||||
|
let expandFlag = ref(false);
|
||||||
|
let handleExpand = () => {
|
||||||
|
expandFlag.value = !expandFlag.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 客户人员
|
||||||
|
let monIndex1= reactive([0]);
|
||||||
|
const changeValue1 = (item, value) => {
|
||||||
|
console.log("客户人员", item, value);
|
||||||
|
monIndex1 = value;
|
||||||
|
};
|
||||||
|
const guestList1 = [
|
||||||
|
{ value: 0, text: "客户1" },
|
||||||
|
{ value: 1, text: "客户2" },
|
||||||
|
{ value: 2, text: "客户3" },
|
||||||
|
{ value: 3, text: "客户4" },
|
||||||
|
{ value: 4, text: "客户5" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 我方人员
|
||||||
|
let monIndex2= reactive([0]);
|
||||||
|
const changeValue2 = (item, value) => {
|
||||||
|
console.log("我方人员", item, value);
|
||||||
|
monIndex2 = value;
|
||||||
|
};
|
||||||
|
const guestList2 = [
|
||||||
|
{ value: 0, text: "我方1" },
|
||||||
|
{ value: 1, text: "我方2" },
|
||||||
|
{ value: 2, text: "我方3" },
|
||||||
|
{ value: 3, text: "我方4" },
|
||||||
|
{ value: 4, text: "我方5" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 活动内容
|
||||||
|
let monIndex3= reactive([0]);
|
||||||
|
const changeValue3 = (item, value) => {
|
||||||
|
console.log("活动内容", item, value);
|
||||||
|
monIndex2 = value;
|
||||||
|
};
|
||||||
|
const guestList3 = [
|
||||||
|
{ value: 0, text: "活动内容1" },
|
||||||
|
{ value: 1, text: "活动内容2" },
|
||||||
|
{ value: 2, text: "活动内容3" },
|
||||||
|
{ value: 3, text: "活动内容4" },
|
||||||
|
{ value: 4, text: "活动内容5" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 业务招待
|
||||||
|
let expandFlag2 = ref(true);
|
||||||
|
let handleExpand2 = () => {
|
||||||
|
expandFlag2.value = !expandFlag2.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 技术交流
|
||||||
|
let expandFlag3 = ref(true);
|
||||||
|
let handleExpand3 = () => {
|
||||||
|
expandFlag3.value = !expandFlag3.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单ref
|
||||||
|
const formRef = ref(null);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref({
|
||||||
|
guestName1: '',
|
||||||
|
guestName2: '',
|
||||||
|
activeCon:'',
|
||||||
|
activeTxt: ''
|
||||||
|
});
|
||||||
|
// 验证规则
|
||||||
|
const rules = {
|
||||||
|
activeCon: {
|
||||||
|
rules: [
|
||||||
|
{ required: true, errorMessage: '请选择活动内容' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
let handleDelete = ()=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
// 保存/修改
|
||||||
|
const submitForm = async () => {
|
||||||
|
try {
|
||||||
|
// 验证表单
|
||||||
|
await formRef.value.validate();
|
||||||
|
|
||||||
|
// 验证通过后的操作
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证通过',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
console.log('表单数据:', formData.value);
|
||||||
|
|
||||||
|
// 这里可以添加提交到服务器的代码
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log('表单验证失败:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.white-bg {
|
||||||
|
width: 690rpx;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg.white-bg-2 {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
.white-bg.white-bg-3 {
|
||||||
|
border-radius:0
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title {
|
||||||
|
color: #3384DF;
|
||||||
|
font-size: 38rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con{
|
||||||
|
padding:30rpx 0 0;
|
||||||
|
}
|
||||||
|
:deep(.form-con .uni-forms-item){
|
||||||
|
margin-bottom:22px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
185
src/pages/business/CRM/vistorCheckin.vue
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'签到打卡'" :leftFlag="true" :rightFlag="false"></customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<image src="../../../static/images/business/btn-qd.png" class="btn-image" @click="handleCheckIn" />
|
||||||
|
<image src="../../../static/images/business/btn-dk.png" class="btn-image" @click="handleClockIn" />
|
||||||
|
<view class="check-desc">
|
||||||
|
业务人员可通过<text class="font-orange">签到</text>或<text class="font-blue">打卡</text>进行行为记录,该时间会和走访报告中的时间进行关联,便于查看。
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 打卡遮罩层 -->
|
||||||
|
<view class="check-con" v-if="checkFlag">
|
||||||
|
<view class="check-in">
|
||||||
|
<view class="check-tip">打卡</view>
|
||||||
|
<view class="check-title">确定要在此处打卡吗?</view>
|
||||||
|
<view class="check-location">
|
||||||
|
<uni-icons type="location-filled" size="30" color="#0395E0"></uni-icons> 亚洲金融大厦
|
||||||
|
</view>
|
||||||
|
<view class="check-address">北京市朝阳区天辰东路1号院</view>
|
||||||
|
<view class="check-footer">
|
||||||
|
<button class="btn-default" type="default" @click="handleCancel" size="mini">取 消</button>
|
||||||
|
<button class="btn-primary" type="primary" @click="handleSubmit" size="mini">确 定</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
|
||||||
|
|
||||||
|
let checkFlag = ref(false);
|
||||||
|
// 签到
|
||||||
|
let handleCheckIn = () => {
|
||||||
|
console.log("签到")
|
||||||
|
checkFlag.value = true;
|
||||||
|
}
|
||||||
|
// 打卡
|
||||||
|
let handleClockIn = () => {
|
||||||
|
console.log("打卡")
|
||||||
|
checkFlag.value = true;
|
||||||
|
}
|
||||||
|
// 取消
|
||||||
|
let handleCancel = () => {
|
||||||
|
checkFlag.value = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
// 确定
|
||||||
|
let handleSubmit = () => {
|
||||||
|
checkFlag.value = false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.white-bg {
|
||||||
|
width: 650rpx;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
padding: 50rpx;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 125px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 98px);
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-image {
|
||||||
|
width: 340rpx;
|
||||||
|
height: 340rpx;
|
||||||
|
margin: 30rpx auto 60rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-desc {
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
padding: 40rpx 50rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 100rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-desc .font-orange {
|
||||||
|
color: #F5813A;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-desc .font-blue {
|
||||||
|
color: #2CBAEF;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹窗处理 */
|
||||||
|
.check-con {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 遮罩层内容样式 */
|
||||||
|
.check-in {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40rpx 30rpx 60rpx;
|
||||||
|
border-radius: 10px;
|
||||||
|
/* width: 620rpx; */
|
||||||
|
width: 560rpx;
|
||||||
|
position: absolute;
|
||||||
|
top: 48%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-in .check-tip {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-in .check-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
}
|
||||||
|
.check-in .check-location{
|
||||||
|
color:#0395E0;
|
||||||
|
font-size:42rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin:30rpx 0;
|
||||||
|
}
|
||||||
|
.check-in .check-location .uniui-location-filled{
|
||||||
|
font-weight: normal;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
.check-in .check-address{
|
||||||
|
color:#919191;
|
||||||
|
font-size: 32rpx;
|
||||||
|
margin-bottom:80rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-in .check-footer {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-in .check-footer .btn-default,
|
||||||
|
.check-in .check-footer .btn-primary {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #05A3F4;
|
||||||
|
color: #05A3F4;
|
||||||
|
border-radius: 25px;
|
||||||
|
padding: 0rpx 80rpx;
|
||||||
|
font-size: 34rpx;
|
||||||
|
/* margin-left: 0;
|
||||||
|
margin-right: 20rpx; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-in .check-footer .btn-primary {
|
||||||
|
background-color: #05A3F4;
|
||||||
|
border: 1px solid #05A3F4;
|
||||||
|
color: #fff;
|
||||||
|
/* padding: 0rpx 60rpx; */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
142
src/pages/business/CRM/weekPlanUpdate.vue
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'修改周计划'" :leftFlag="true" :rightFlag="true">
|
||||||
|
<template #right>
|
||||||
|
<view class="head-right" @click="submitForm">
|
||||||
|
<uni-icons custom-prefix="iconfont" type="icon-phonebaocun" size="22"
|
||||||
|
color="#B7D2FF"></uni-icons>保存
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</customHeader>
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<view class="week-plan-title">
|
||||||
|
<view>姓名:赵欣鸣</view>
|
||||||
|
<view>2025-09 第 3 周</view>
|
||||||
|
</view>
|
||||||
|
<view class="white-bg white-bg-2">
|
||||||
|
<view class="w-b-title">2025-09-21 星期一
|
||||||
|
<text>
|
||||||
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view class="form-con">
|
||||||
|
<uni-forms ref="formRef" :model="formData" :rules="rules" label-width="100px" label-position="top">
|
||||||
|
<uni-forms-item label="工作类型" name="workType">
|
||||||
|
<view class="form-picker">
|
||||||
|
<picker @change="changeValue" :value="workIndex" :range="workList">
|
||||||
|
<view class="flex">
|
||||||
|
{{workList[workIndex]}}
|
||||||
|
<uni-icons type="down" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
</view>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="内容" name="content">
|
||||||
|
<uni-easyinput type="textarea" autoHeight v-model="formData.content" placeholder="请输入" class="form-texarea" />
|
||||||
|
</uni-forms-item>
|
||||||
|
</uni-forms>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import multipleSelect from '@/components/multipleSelect.vue'
|
||||||
|
|
||||||
|
// 工作类型
|
||||||
|
let workIndex= ref(0);
|
||||||
|
const workList = ["外出","出差","公司","办事处"];
|
||||||
|
|
||||||
|
// 表单ref
|
||||||
|
const formRef = ref(null);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref({
|
||||||
|
workType:'',
|
||||||
|
content: ''
|
||||||
|
});
|
||||||
|
// 验证规则
|
||||||
|
const rules = {
|
||||||
|
workType: {
|
||||||
|
rules: [
|
||||||
|
{ required: true, errorMessage: '请选择工作类型' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 选择工作类型
|
||||||
|
const changeValue = (e) => {
|
||||||
|
console.log("工作类型", e.detail.value);
|
||||||
|
workIndex = e.detail.value;
|
||||||
|
formData.value.workType = workList[workIndex]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存
|
||||||
|
const submitForm = async () => {
|
||||||
|
try {
|
||||||
|
// 验证表单
|
||||||
|
await formRef.value.validate();
|
||||||
|
|
||||||
|
// 验证通过后的操作
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证通过',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
console.log('表单数据:', formData.value);
|
||||||
|
|
||||||
|
// 这里可以添加提交到服务器的代码
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log('表单验证失败:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.week-plan-title{
|
||||||
|
color:#fff;
|
||||||
|
padding: 0 30rpx 30rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.white-bg {
|
||||||
|
width: 690rpx;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg.white-bg-2 {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
.white-bg.white-bg-3 {
|
||||||
|
border-radius:0
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title {
|
||||||
|
color: #3384DF;
|
||||||
|
font-size: 38rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con{
|
||||||
|
padding:30rpx 0 0;
|
||||||
|
}
|
||||||
|
:deep(.form-con .uni-forms-item){
|
||||||
|
margin-bottom:22px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
181
src/pages/business/business.vue
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'业务中心'"
|
||||||
|
:leftFlag="false" :rightFlag="false"
|
||||||
|
></customHeader>
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<view class="search">
|
||||||
|
<uni-search-bar class="custom-search" radius="28"
|
||||||
|
placeholder="请输入您想查询的内容或服务"
|
||||||
|
clearButton="auto" cancelButton="none"
|
||||||
|
bgColor="#6FA2F8" textColor="#ffffff"
|
||||||
|
@confirm="handleSearch"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 下拉刷新 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit"
|
||||||
|
:down="downOption" @down="downCallback"
|
||||||
|
:fixed="false" class="scroll-h"
|
||||||
|
>
|
||||||
|
<!-- 首页日常服务 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="w-b-title">
|
||||||
|
首页日常服务
|
||||||
|
<view type="primary" @click="handleEdit" class="btn-edit">编 辑</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 企业日常 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="w-b-title" @click="handleExpand">企业日常
|
||||||
|
<text>{{expandFlag?'展开':'收起'}}<i :class="{iconfont:true,'icon-up':!expandFlag,'icon-down':expandFlag}"></i></text>
|
||||||
|
</view>
|
||||||
|
<view class="logo-list" v-if="!expandFlag">
|
||||||
|
<view v-for="(item,index) in list1" class="l-l-item" :key="index">
|
||||||
|
<img :src="item.imgSrc" />
|
||||||
|
<text class="font-gray">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- CRM系统 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="w-b-title" @click="handleExpand2">CRM系统
|
||||||
|
<text>{{expandFlag2?'展开':'收起'}}<i :class="{iconfont:true,'icon-up':!expandFlag2,'icon-down':expandFlag2}"></i></text>
|
||||||
|
</view>
|
||||||
|
<view class="logo-list" v-if="!expandFlag2">
|
||||||
|
<view v-for="(item,index) in list2" class="l-l-item" :key="index" @click="handleJump(item.url)">
|
||||||
|
<uni-badge :text="item.badgeCount" size="small"></uni-badge>
|
||||||
|
<img :src="item.imgSrc" />
|
||||||
|
<text class="font-gray">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 供应链采纳 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="w-b-title">供应链采纳
|
||||||
|
<text>展开<i :class="{iconfont:true,'icon-down':true}"></i></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- PLM系统 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="w-b-title">PLM系统
|
||||||
|
<text>展开<i :class="{iconfont:true,'icon-down':true}"></i></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部加高度来避免tabbar遮挡 -->
|
||||||
|
<view class="bottom-height"></view>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import { getNavBarPaddingTop} from '@/utils/system.js'
|
||||||
|
import { businessDaily,businessCRMList } from '@/api/business.js';
|
||||||
|
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop()*2;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查询搜索跳转
|
||||||
|
let handleSearch = ()=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
const downOption = ref({
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
// mescroll.resetUpScroll();
|
||||||
|
},500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
mescroll.endSuccess();
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日常服务编辑
|
||||||
|
let handleEdit=()=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图标查询处理
|
||||||
|
// 1.企业日常
|
||||||
|
let list1 = ref([])
|
||||||
|
let getBusinessDailyList= async ()=>{
|
||||||
|
let busRes = await businessDaily({});
|
||||||
|
list1.value = busRes.list || [];
|
||||||
|
}
|
||||||
|
getBusinessDailyList();
|
||||||
|
// 企业日常-右侧展开
|
||||||
|
let expandFlag=ref(false);
|
||||||
|
let handleExpand = ()=>{
|
||||||
|
expandFlag.value = !expandFlag.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.CRM系统
|
||||||
|
let list2 = ref([])
|
||||||
|
let getBusinessCRMList= async ()=>{
|
||||||
|
let busRes = await businessCRMList({});
|
||||||
|
list2.value = busRes.list || [];
|
||||||
|
}
|
||||||
|
getBusinessCRMList();
|
||||||
|
// 企业日常-右侧展开
|
||||||
|
let expandFlag2=ref(false);
|
||||||
|
let handleExpand2 = ()=>{
|
||||||
|
expandFlag2.value = !expandFlag2.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转
|
||||||
|
let handleJump=(url)=>{
|
||||||
|
console.log(url)
|
||||||
|
if(url){
|
||||||
|
uni.navigateTo({ url })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scope>
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 120px) !important;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 140px) !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
:deep(.mescroll-upwarp){
|
||||||
|
display:none
|
||||||
|
}
|
||||||
|
</style>
|
||||||
430
src/pages/home/home.vue
Normal file
@@ -0,0 +1,430 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 下拉刷新 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit"
|
||||||
|
:down="downOption" @down="downCallback"
|
||||||
|
:fixed="false" class="scroll-h" :style="{ paddingTop: navBarPaddingTop + 'px' }"
|
||||||
|
>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<view style="height:50rpx"></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<view class="search search-sao" >
|
||||||
|
<uni-search-bar class="custom-search" radius="28"
|
||||||
|
placeholder="请输入您想查询的内容或服务"
|
||||||
|
clearButton="auto" cancelButton="none"
|
||||||
|
bgColor="#6FA2F8" textColor="#ffffff"
|
||||||
|
@confirm="handleSearch"
|
||||||
|
/>
|
||||||
|
<uni-icons custom-prefix="iconfont" color="#ffffff" type="icon-phonesaoyisao" size="20"></uni-icons>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 待办内容 -->
|
||||||
|
<view class="backlog-bg">
|
||||||
|
<view class="backlog-b-item">
|
||||||
|
<view class="font-number">{{ backBlogObj.count1 }}</view>
|
||||||
|
<view class="font-title">待办</view>
|
||||||
|
</view>
|
||||||
|
<view class="backlog-b-item">
|
||||||
|
<view class="font-number">{{ backBlogObj.count2 }}</view>
|
||||||
|
<view class="font-title">待审查</view>
|
||||||
|
</view>
|
||||||
|
<view class="backlog-b-item">
|
||||||
|
<view class="font-number">{{ backBlogObj.count3 }}</view>
|
||||||
|
<view class="font-title">待巡检</view>
|
||||||
|
</view>
|
||||||
|
<view class="backlog-b-item">
|
||||||
|
<view class="font-number">{{ backBlogObj.count4 }}</view>
|
||||||
|
<view class="font-title">待发货</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 跑马灯滚动 -->
|
||||||
|
<view class="notice-bg">
|
||||||
|
<img :src="'static/images/icon-notice@2x.png'" class="notice-icon" />
|
||||||
|
<view class="notice-list">
|
||||||
|
<!-- :interval="4000" -->
|
||||||
|
<swiper class="swiper-con"
|
||||||
|
:vertical="true"
|
||||||
|
:autoplay="true"
|
||||||
|
:duration="500"
|
||||||
|
:circular="true"
|
||||||
|
:disable-touch="true"
|
||||||
|
:display-multiple-items="1"
|
||||||
|
>
|
||||||
|
<swiper-item v-for="(item, index) in extendedList" :key="index" >
|
||||||
|
<view class="swiper-item">
|
||||||
|
{{ item }}
|
||||||
|
</view>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 日程提醒 -->
|
||||||
|
<view class="white-bg mar-top" v-if="stepList.length>0">
|
||||||
|
<view class="w-b-title">日程提醒
|
||||||
|
<view class="yellow-bg">
|
||||||
|
<i :class="{iconfont:true,'icon-phoneshizhong':true}"></i>
|
||||||
|
<view class="text-black">{{ weekStr }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="section-line">
|
||||||
|
<customSteps :steps="stepList" :modelValue="stepList"></customSteps>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 销售任务完成情况 -->
|
||||||
|
<view class="white-bg mar-top">
|
||||||
|
<view class="w-b-title">销售任务完成情况
|
||||||
|
<view class="yellow-bg">
|
||||||
|
<picker @change="bindPickerChange" :value="activeIndex" :range="salesList" @click="clickPicker" @cancel="bindPickerCancel">
|
||||||
|
<view class="uni-input">{{salesList[activeIndex]}}</view>
|
||||||
|
</picker>
|
||||||
|
<i :class="{iconfont:true,'icon-down':salesFlag,'icon-up':!salesFlag}" class="picker-icon"></i>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="progress-bg">
|
||||||
|
<progress :percent="percentNum" stroke-width="10" activeColor="#41E1B1" backgroundColor="#F0F0F0" />
|
||||||
|
<view class="percent" :style="{left:percentNum+'%'}">
|
||||||
|
<view class="percent-num">{{ percentNum }}%</view>
|
||||||
|
<i class="iconfont icon-down"></i>
|
||||||
|
</view>
|
||||||
|
<view class="percent-con">
|
||||||
|
<view class="p-first">
|
||||||
|
<view>实际销售额</view>
|
||||||
|
<view class="font-money">{{totalSales}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="p-last">
|
||||||
|
<view>目标销售额</view>
|
||||||
|
<view class="font-money">{{ targetSales }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 常用服务 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="w-b-title">常用服务</view>
|
||||||
|
<view class="logo-list">
|
||||||
|
<view v-for="(item,index) in commonServiceList" class="l-l-item" :key="index">
|
||||||
|
<img :src="item.imgSrc" />
|
||||||
|
<text class="font-gray">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
<!-- <view class="l-l-item" @click="handleAddCommonSercice">
|
||||||
|
<img :src="'static/images/business/icon-add.png'">
|
||||||
|
<text class="font-gray">添加</text>
|
||||||
|
</view> -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 新闻公告 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="w-b-title">新闻公告
|
||||||
|
<text>更多新闻</text>
|
||||||
|
</view>
|
||||||
|
<view class="news-list">
|
||||||
|
<view v-for="(item,index) in newsList" class="news-item" :key="index">
|
||||||
|
<view class="n-i-title">{{ item.name }}
|
||||||
|
<view class="n-i-date">{{ formatDateStr(item.date) }}</view>
|
||||||
|
</view>
|
||||||
|
<img :src="item.imgSrc" v-if="item.imgSrc" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部加高度来避免tabbar遮挡 -->
|
||||||
|
<view class="bottom-height"></view>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,onMounted,computed } from 'vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import customSteps from '@/components/customSteps.vue'
|
||||||
|
import { getNavBarPaddingTop} from '@/utils/system.js'
|
||||||
|
import { backBlogCount,swiperList,stepData,salesTask,commonServices,newsQueryList } from '@/api/home.js';
|
||||||
|
import { getWeekStr,formatTimestamp } from '@/utils/datetime.js'
|
||||||
|
import { formatMoney } from '@/utils/formatter.js'
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
const downOption = ref({
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
// mescroll.resetUpScroll();
|
||||||
|
},500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
mescroll.endSuccess();
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop()*2;
|
||||||
|
})
|
||||||
|
// 查询搜索跳转
|
||||||
|
let handleSearch = ()=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// tabar 增加消息数量
|
||||||
|
try {
|
||||||
|
wx.setTabBarBadge({
|
||||||
|
index: 2, // TabBar的索引,从0开始计数
|
||||||
|
text: '3' // 徽章的文本
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('设置TabBar Badge失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
let backBlogObj = ref({})
|
||||||
|
// 获取待办数据
|
||||||
|
let getBackBlogCount = async () =>{
|
||||||
|
backBlogObj.value = await backBlogCount();
|
||||||
|
}
|
||||||
|
getBackBlogCount();
|
||||||
|
|
||||||
|
// 跑马灯处理
|
||||||
|
let extendedList = ref([]);// ;
|
||||||
|
const getSwiperList = async () => {
|
||||||
|
extendedList.value = await swiperList();
|
||||||
|
}
|
||||||
|
getSwiperList();
|
||||||
|
|
||||||
|
// 日程提醒
|
||||||
|
let weekStr = ref(null) //'2025-09-19 星期三'
|
||||||
|
let stepList = ref([]);
|
||||||
|
const getStepData = async ()=>{
|
||||||
|
let res = await stepData({});
|
||||||
|
weekStr.value = getWeekStr(res.date);
|
||||||
|
stepList.value = res.list;
|
||||||
|
}
|
||||||
|
getStepData();
|
||||||
|
|
||||||
|
// 销售任务完成情况
|
||||||
|
let salesList = ref([]);
|
||||||
|
let salesFlag = ref(true);
|
||||||
|
let activeIndex = ref(0);
|
||||||
|
const bindPickerChange = (e)=>{
|
||||||
|
// console.log('picker发送选择改变,携带值为', e.detail.value)
|
||||||
|
activeIndex.value = e.detail.value;
|
||||||
|
salesFlag.value = true;
|
||||||
|
}
|
||||||
|
const bindPickerCancel= (e)=>{
|
||||||
|
salesFlag.value = true;
|
||||||
|
}
|
||||||
|
const clickPicker= (e)=>{
|
||||||
|
salesFlag.value = false;
|
||||||
|
}
|
||||||
|
let percentNum = ref(0);
|
||||||
|
let totalSales = ref(0)
|
||||||
|
let targetSales = ref(0)
|
||||||
|
const getSalesTask = async ()=>{
|
||||||
|
let res = await salesTask({});
|
||||||
|
salesList.value = res.salesList;
|
||||||
|
percentNum.value = res.percentNum;
|
||||||
|
totalSales.value = formatMoney(res.totalSales);
|
||||||
|
targetSales.value = formatMoney(res.targetSales);
|
||||||
|
}
|
||||||
|
getSalesTask();
|
||||||
|
|
||||||
|
// 常用服务
|
||||||
|
let commonServiceList = ref([])
|
||||||
|
const getCommonServices = async ()=>{
|
||||||
|
let res = await commonServices({});
|
||||||
|
commonServiceList.value = res.list
|
||||||
|
}
|
||||||
|
getCommonServices();
|
||||||
|
// 添加常用服务
|
||||||
|
const handleAddCommonSercice = ()=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新闻公告
|
||||||
|
let newsList = ref([])
|
||||||
|
const getNewsList = async()=>{
|
||||||
|
let res = await newsQueryList({});
|
||||||
|
newsList.value = res.list;
|
||||||
|
}
|
||||||
|
getNewsList();
|
||||||
|
const formatDateStr =(times)=>{
|
||||||
|
return formatTimestamp(times)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scope>
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:calc(100vh - 30px) !important;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 30px) !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
:deep(.mescroll-upwarp){
|
||||||
|
display:none
|
||||||
|
}
|
||||||
|
.search-sao{
|
||||||
|
display: flex;
|
||||||
|
padding-top:10rpx;
|
||||||
|
}
|
||||||
|
.search-sao .custom-search{
|
||||||
|
width:612rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
.search-sao :deep(.custom-search.uni-searchbar){
|
||||||
|
padding-bottom: 15rpx !important;
|
||||||
|
}
|
||||||
|
.search-sao .icon-phonesaoyisao{
|
||||||
|
margin:15rpx 30rpx 10rpx auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backlog-bg{
|
||||||
|
background:url('@/static/images/bg-main@2x.png') no-repeat;
|
||||||
|
background-size:730rpx 205rpx;
|
||||||
|
/* width:730rpx; */
|
||||||
|
width:690rpx;
|
||||||
|
height:205rpx;
|
||||||
|
margin:0 auto;
|
||||||
|
display: flex;
|
||||||
|
padding:0 20rpx;
|
||||||
|
}
|
||||||
|
.backlog-b-item{
|
||||||
|
width:25%;
|
||||||
|
color:#579FF9;
|
||||||
|
border-right:1px solid #EAEAEA;
|
||||||
|
height:100rpx;
|
||||||
|
margin-top:40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backlog-b-item .font-number{
|
||||||
|
font-size: 60rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.backlog-b-item .font-title{
|
||||||
|
font-size:28rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notice-bg{
|
||||||
|
background:url('@/static/images/bg-notice@2x.png') no-repeat;
|
||||||
|
background-size:750rpx 90rpx;
|
||||||
|
width:690rpx;
|
||||||
|
height: 90rpx;
|
||||||
|
margin-top:10rpx;
|
||||||
|
padding:0 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.notice-bg .notice-icon{
|
||||||
|
width:46rpx;
|
||||||
|
height:40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notice-list{
|
||||||
|
width:100%;
|
||||||
|
position: relative;
|
||||||
|
height: 90rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.notice-list .swiper-con{
|
||||||
|
width:640rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notice-list .swiper-con .swiper-item {
|
||||||
|
height: 90rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color:#fff;
|
||||||
|
font-size:30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bg{
|
||||||
|
position: relative;
|
||||||
|
width:528rpx;
|
||||||
|
margin:120rpx auto 0;
|
||||||
|
}
|
||||||
|
.progress-bg :deep(.uni-progress .uni-progress-bar){
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bg :deep(.uni-progress .uni-progress-inner-bar){
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
}
|
||||||
|
.progress-bg .percent{
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
color:#FF687A;
|
||||||
|
font-size:60rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.progress-bg .percent .icon-down{
|
||||||
|
position: absolute;
|
||||||
|
bottom:0rpx;
|
||||||
|
left:-20rpx;
|
||||||
|
color:#FF687A;
|
||||||
|
font-size:40rpx;
|
||||||
|
}
|
||||||
|
.progress-bg .percent .percent-num{
|
||||||
|
position: absolute;
|
||||||
|
left:-60rpx;
|
||||||
|
bottom:30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bg .percent-con{
|
||||||
|
display: flex;
|
||||||
|
width:528rpx;
|
||||||
|
color:#333;
|
||||||
|
font-size:28rpx;
|
||||||
|
margin:20rpx 0 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bg .percent-con .p-last{
|
||||||
|
margin-left: auto;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.progress-bg .percent-con .font-money{
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top:10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .logo-list{
|
||||||
|
gap:50rpx;
|
||||||
|
padding:0 20rpx;
|
||||||
|
/* margin-bottom: -50rpx; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .logo-list .l-l-item{
|
||||||
|
width:160rpx;
|
||||||
|
margin-bottom:0rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .logo-list .l-l-item img{
|
||||||
|
width:110rpx;
|
||||||
|
height:110rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
86
src/pages/loading/loading.vue
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="container" :style="{ height: `100vh` }">
|
||||||
|
<view class="bg"></view>
|
||||||
|
<view class="version">Version {{ version }}</view>
|
||||||
|
<view class="bottom-bg"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { useUserStore } from '@/stores/user';
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const version="1.0.0"
|
||||||
|
|
||||||
|
onLoad((opt) => {
|
||||||
|
console.log("onLoad");
|
||||||
|
// 检查是否已登录 并 获取用户信息
|
||||||
|
if (userStore.isLogin) {
|
||||||
|
// userStore.getUser()
|
||||||
|
// TODO 未登录会在拦截器中处理跳转登录页, 请在 xxx 配置登录页路径
|
||||||
|
// #ifdef H5
|
||||||
|
window.setTimeout(()=>{
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/home/home',
|
||||||
|
});
|
||||||
|
},1000)
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/home/home',
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
}else{
|
||||||
|
// #ifdef H5
|
||||||
|
window.setTimeout(()=>{
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/login',
|
||||||
|
});
|
||||||
|
},1000)
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/login',
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
background:#307AF5 !important;
|
||||||
|
height:100vh !important;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.container .bg{
|
||||||
|
background:url('@/static/images/loading-logo.png') no-repeat;
|
||||||
|
background-size:700rpx 800rpx;
|
||||||
|
width: 700rpx;
|
||||||
|
height: 800rpx;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
.container .version{
|
||||||
|
color:#A8D4FF;
|
||||||
|
font-size:32rpx;
|
||||||
|
text-align: center;
|
||||||
|
margin-top:35rpx;
|
||||||
|
}
|
||||||
|
.container .bottom-bg{
|
||||||
|
background:url('@/static/images/loading-txt.png') no-repeat;
|
||||||
|
background-size:656rpx 123rpx;
|
||||||
|
width: 656rpx;
|
||||||
|
height: 123rpx;
|
||||||
|
position: absolute;
|
||||||
|
bottom:48rpx;
|
||||||
|
left:50%;
|
||||||
|
margin-left:-328rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
413
src/pages/login/login.vue
Normal file
@@ -0,0 +1,413 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="login-con">
|
||||||
|
<view :style="{height: navBarPaddingTop + 'px'}"></view>
|
||||||
|
<image mode="aspectFit" src="../../static/images/pic-logo.png" class="login-logo"></image>
|
||||||
|
<view class="login-title">欢迎来到718友晟</view>
|
||||||
|
<view class="login-tab">
|
||||||
|
<customTabs v-model="activeTab" :tabs="tabList" :modelValue="activeTab">
|
||||||
|
<!-- 验证码登录 -->
|
||||||
|
<view v-show="activeTab === 0">
|
||||||
|
<view class="login-form">
|
||||||
|
<uni-forms ref="form" :model="formData" :rules="rules" label-position="top">
|
||||||
|
<uni-forms-item label="手机号" required name="phone">
|
||||||
|
<view class="code-con">
|
||||||
|
<uni-icons custom-prefix="iconfont" color="#239FDF" type="icon-phone" size="20"></uni-icons>
|
||||||
|
<uni-easyinput type="number" :inputBorder="false"
|
||||||
|
v-model="formData.phone" placeholder="请输入手机号"
|
||||||
|
maxlength="11"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="验证码" required name="verifyCode">
|
||||||
|
<view class="code-con">
|
||||||
|
<uni-icons custom-prefix="iconfont" color="#239FDF" type="icon-code" size="20"></uni-icons>
|
||||||
|
<uni-easyinput type="number" :inputBorder="false"
|
||||||
|
v-model="formData.verifyCode" placeholder="请输入验证码"
|
||||||
|
maxlength="6" style="width:190rpx"
|
||||||
|
/>
|
||||||
|
<button type="primary" plain @click="getCode" size="mini"
|
||||||
|
:loading="codeLoading" :disabled="codeDisabled" class="btn-plain"
|
||||||
|
>{{codeText}}</button>
|
||||||
|
</view>
|
||||||
|
</uni-forms-item>
|
||||||
|
</uni-forms>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 账号登录 -->
|
||||||
|
<view v-show="activeTab === 1">
|
||||||
|
<view class="login-form">
|
||||||
|
<uni-forms ref="form2" :model="formData2" :rules="rules2" label-position="top">
|
||||||
|
<uni-forms-item label="用户名" required name="username">
|
||||||
|
<view class="code-con">
|
||||||
|
<uni-easyinput prefixIcon="person" :inputBorder="false"
|
||||||
|
v-model="formData2.username" placeholder="请输入用户名"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="密码" required name="password" class="password">
|
||||||
|
<view class="code-con">
|
||||||
|
<uni-easyinput prefixIcon="locked" type="password" :inputBorder="false"
|
||||||
|
v-model="formData2.password" placeholder="请输入登录密码"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</uni-forms-item>
|
||||||
|
</uni-forms>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</customTabs>
|
||||||
|
|
||||||
|
<view class="agreen-con">
|
||||||
|
<uni-icons v-if="agreeChecked" type="checkbox-filled" color="#02C74C" size="25" @click="agreeCheck"></uni-icons>
|
||||||
|
<uni-icons v-else type="circle" color="#bfbfbf" size="25" @click="agreeCheck"></uni-icons>
|
||||||
|
<view class="agreen-xy">
|
||||||
|
我已阅读并接受<text @click="agreeVisable(1)">《服务条款》</text>和<text @click="agreeVisable(2)">《隐私保护协议》</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button type="primary" class="btn-submit" @click="submitForm" :loading="btnLoading" :disabled="btnLoading">登 录</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="login-bottom"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,onMounted } from 'vue';
|
||||||
|
import customTabs from '@/components/customTabs.vue';
|
||||||
|
import {isPhoneNumber} from '@/utils/validate';
|
||||||
|
import {showAlert} from '@/utils/message';
|
||||||
|
import { getCaptchaImage,getVerifyCode,login } from '@/api/auth';
|
||||||
|
import cache from '@/utils/cache';
|
||||||
|
import { AGREEWELCOME_KEY } from '@/enums/cacheEnums';
|
||||||
|
|
||||||
|
import { getNavBarPaddingTop} from '@/utils/system.js'
|
||||||
|
|
||||||
|
import { useUserStore } from '@/stores/user';
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop();
|
||||||
|
})
|
||||||
|
|
||||||
|
const activeTab = ref(1);//默认账号登录
|
||||||
|
const tabList = ['验证码登录', '账号登录'];
|
||||||
|
|
||||||
|
// 验证码登录
|
||||||
|
const form = ref(null);
|
||||||
|
const formData = ref({
|
||||||
|
phone: '15112345600',
|
||||||
|
verifyCode: '123456',
|
||||||
|
loginType:0
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
phone: {
|
||||||
|
rules: [
|
||||||
|
{ required: true, errorMessage: '请输入手机号' },
|
||||||
|
{
|
||||||
|
validateFunction:function(rule,value,data,callback){
|
||||||
|
if (!isPhoneNumber(value)) {
|
||||||
|
callback('请正确输入手机号')
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
verifyCode: {
|
||||||
|
rules: [
|
||||||
|
{ required: true, errorMessage: '请输入验证码' },
|
||||||
|
{ pattern: /^[0-9]{6}$/, errorMessage: '验证码必须是6位数字' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let codeLoading = ref(false);
|
||||||
|
let codeDisabled = ref(false);
|
||||||
|
let codeText = ref('发送验证码');
|
||||||
|
let countdown = ref(60);
|
||||||
|
let timer = ref(null);
|
||||||
|
let backCode=ref(null)
|
||||||
|
|
||||||
|
// 验证特定字段
|
||||||
|
const validateField = async (fieldName) => {
|
||||||
|
try {
|
||||||
|
await form.value.validateField(fieldName);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 发送验证码
|
||||||
|
let getCode=async()=> {
|
||||||
|
|
||||||
|
// 1.验证手机号
|
||||||
|
const isValid = await validateField('phone');
|
||||||
|
if (isValid) {
|
||||||
|
codeLoading.value = true;
|
||||||
|
codeDisabled.value = true;
|
||||||
|
// 2.调用获取短信验证码接口
|
||||||
|
let res = await getVerifyCode({phone:formData.value.phone})
|
||||||
|
backCode.value = res.code;
|
||||||
|
codeText.value = `发送中...`;
|
||||||
|
|
||||||
|
// 3.开始倒计时
|
||||||
|
startCountdown();
|
||||||
|
}
|
||||||
|
// showAlert("验证码已发送!",'提示',false);
|
||||||
|
}
|
||||||
|
let startCountdown=()=>{
|
||||||
|
if (timer.value) return;
|
||||||
|
timer.value = setInterval(() => {
|
||||||
|
if (countdown.value > 0) {
|
||||||
|
countdown.value--;
|
||||||
|
codeText.value = `${countdown.value} 秒`;
|
||||||
|
} else {
|
||||||
|
resetCountdown();
|
||||||
|
}
|
||||||
|
codeLoading.value = false;
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
let resetCountdown =()=>{
|
||||||
|
clearInterval(timer.value);
|
||||||
|
timer.value = null;
|
||||||
|
countdown.value = 60;
|
||||||
|
codeText.value = '发送验证码';
|
||||||
|
codeDisabled.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 账号登录
|
||||||
|
const form2 = ref(null);
|
||||||
|
const formData2 = ref({
|
||||||
|
username: 'admin',
|
||||||
|
password: '123456',
|
||||||
|
loginType:1
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules2 = {
|
||||||
|
username: {
|
||||||
|
rules: [
|
||||||
|
{ required: true, errorMessage: '请输入用户名' },
|
||||||
|
{ minLength: 3, maxLength: 10, errorMessage: '用户名长度在3到10个字符之间' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
rules: [
|
||||||
|
{ required: true, errorMessage: '请输入密码' },
|
||||||
|
{ pattern: /^[a-zA-Z0-9]{6,12}$/, errorMessage: '密码必须是6-12位字母或数字' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 协议
|
||||||
|
let agreeChecked = ref(true);
|
||||||
|
// 勾选同意协议 存入缓存
|
||||||
|
const agreeCheck = ()=>{
|
||||||
|
agreeChecked.value = !agreeChecked.value;
|
||||||
|
if (agreeChecked.value) {
|
||||||
|
cache.set(AGREEWELCOME_KEY, agreeChecked.value)
|
||||||
|
} else {
|
||||||
|
cache.remove(AGREEWELCOME_KEY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const btnLoading=ref(false)
|
||||||
|
// 登录提交
|
||||||
|
const submitForm = () => {
|
||||||
|
|
||||||
|
btnLoading.value = true;
|
||||||
|
console.log("submitForm=>activeTab=>",activeTab.value)
|
||||||
|
// 手机获取验证码登录
|
||||||
|
if(activeTab.value===0){
|
||||||
|
form.value.validate().then(async param => {
|
||||||
|
// 2.调用登录接口
|
||||||
|
param.loginType = activeTab.value; console.log('表单数据00:', param);
|
||||||
|
let res = await login(param)
|
||||||
|
// 3.登录后存储token
|
||||||
|
userStore.login(res);
|
||||||
|
uni.switchTab({ url: '/pages/home/home' })
|
||||||
|
btnLoading.value = false;
|
||||||
|
}).catch(err => {
|
||||||
|
console.log('表单错误00:', err);
|
||||||
|
btnLoading.value = false;
|
||||||
|
});
|
||||||
|
}else if(activeTab.value===1){
|
||||||
|
// 用户名和密码登录
|
||||||
|
form2.value.validate().then(async param => {
|
||||||
|
param.loginType = activeTab.value; console.log('表单数据11:', formData2.value);
|
||||||
|
let res = await login(param);
|
||||||
|
userStore.login(res);
|
||||||
|
uni.switchTab({ url: '/pages/home/home' })
|
||||||
|
btnLoading.value = false;
|
||||||
|
}).catch(err => {
|
||||||
|
console.log('表单错误11:', err);
|
||||||
|
btnLoading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-con {
|
||||||
|
position: relative;
|
||||||
|
background: url('@/static/images/login-bg.png') no-repeat;
|
||||||
|
background-size: 750rpx 633rpx;
|
||||||
|
width: 750rpx;
|
||||||
|
height: 633rpx;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-con .login-logo {
|
||||||
|
width: 109rpx;
|
||||||
|
height: 91rpx;
|
||||||
|
margin: 84rpx 0 0 70rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-con .login-title {
|
||||||
|
font-size: 56rpx;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0 0 35rpx 70rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.login-tab .tabs-header) {
|
||||||
|
background: none !important;
|
||||||
|
border-bottom: none !important;
|
||||||
|
width: 438rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.login-tab .tab-item) {
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.tab-item.active) {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.tab-item.active::after) {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100rpx;
|
||||||
|
height: 8rpx;
|
||||||
|
/* display: none; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
padding: 30rpx 50rpx 15rpx;
|
||||||
|
width:510rpx;
|
||||||
|
margin: 20rpx auto 0;
|
||||||
|
box-shadow: 0rpx -1rpx 16rpx 0rpx rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-con{
|
||||||
|
padding:0 0 10rpx;
|
||||||
|
margin:0 auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color:#919191;
|
||||||
|
border-bottom: 1px solid #E7E7E7;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.uni-forms-item__label){
|
||||||
|
color:#239FDF;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size:28rpx;
|
||||||
|
padding:0 !important;
|
||||||
|
}
|
||||||
|
:deep(.uni-easyinput__content){
|
||||||
|
color:#333;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size:32rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
:deep(.uni-easyinput__content) .uni-icons{
|
||||||
|
font-weight: normal;
|
||||||
|
font-size:24rpx;
|
||||||
|
color:#239FDF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.uni-input-placeholder){
|
||||||
|
background:none;
|
||||||
|
font-weight:normal;
|
||||||
|
color:#BFBFBF;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
:deep(.uni-forms-item__error){
|
||||||
|
padding-left:60rpx;
|
||||||
|
}
|
||||||
|
:deep(.uni-forms-item .is-required){
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 使用深度选择器 */
|
||||||
|
:deep(.uni-easyinput__content .uni-icons.uniui-clear) {
|
||||||
|
color: #BFBFBF !important;
|
||||||
|
font-weight: normal !important;
|
||||||
|
font-size:40rpx !important;
|
||||||
|
}
|
||||||
|
:deep(.uni-easyinput__content .uni-icons.uniui-clear::before){
|
||||||
|
content: "\e66c" !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreen-con{
|
||||||
|
margin-top:40rpx;
|
||||||
|
color:#919191;
|
||||||
|
font-size:26rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.agreen-con .agreen-xy{
|
||||||
|
margin-left:10rpx;
|
||||||
|
}
|
||||||
|
.agreen-con text{
|
||||||
|
color:#05A3F4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-plain{
|
||||||
|
color: #05A3F4 !important;
|
||||||
|
border: 1px solid #05A3F4 !important;
|
||||||
|
/* padding:0 30rpx; */
|
||||||
|
font-size:24rpx;
|
||||||
|
/* line-height: 2.1; */
|
||||||
|
/* width:230rpx; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-submit{
|
||||||
|
width:490rpx;
|
||||||
|
height:88rpx;
|
||||||
|
line-height: 88rpx;
|
||||||
|
background-color:#05A3F4 !important;
|
||||||
|
margin:80rpx auto 0;
|
||||||
|
font-size:36rpx;
|
||||||
|
border-radius: 44rpx;
|
||||||
|
}
|
||||||
|
.btn-submit::after{
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-bottom{
|
||||||
|
position: absolute;
|
||||||
|
background: url('../../static/images/login-txt.png');
|
||||||
|
background-size:654rpx 121rpx;
|
||||||
|
width:654rpx;
|
||||||
|
height: 121rpx;
|
||||||
|
bottom:30rpx;
|
||||||
|
left:50%;
|
||||||
|
margin-left:-327rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
234
src/pages/notice/notice.vue
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="'消息'" :leftFlag="false" :rightFlag="true">
|
||||||
|
<template #right>
|
||||||
|
<view class="head-right" @click="handleReady">
|
||||||
|
<img :src="'static/images/notice/icon-clean@2x.png'" />清除未读
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</customHeader>
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<view class="search">
|
||||||
|
<uni-search-bar class="custom-search" radius="28" placeholder="请输入您想查询的内容或服务" clearButton="auto"
|
||||||
|
cancelButton="none" bgColor="#6FA2F8" textColor="#ffffff" @confirm="handleSearch" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 消息列表 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
|
||||||
|
:up="upOption" :down="downOption" :fixed="false" class="scroll-h" :class="{'loading-scroll':cssFlag}">
|
||||||
|
<view class="white-bg" v-if="list.length">
|
||||||
|
<view class="notice-list" v-for="(item, index) in list" :key="index">
|
||||||
|
<img :src="item.imgSrc" />
|
||||||
|
<view class="notice-item">
|
||||||
|
<view :class="{ 'notice-title': true, bold: item.isReady }">{{ item.title }}</view>
|
||||||
|
<view class="notice-date">{{ formatDateStr(item.date) }}</view>
|
||||||
|
<view class="dot" v-if="item.isReady"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import { getNavBarPaddingTop } from '@/utils/system.js'
|
||||||
|
import { noticeList } from '@/api/notice.js'
|
||||||
|
import { formatTimestamp } from '@/utils/datetime.js'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查询搜索跳转
|
||||||
|
let handleSearch = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDateStr = (times) => {
|
||||||
|
return formatTimestamp(times)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除未读
|
||||||
|
const handleReady = () => {
|
||||||
|
list.value.forEach(item => {
|
||||||
|
item.isReady = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询通知列表
|
||||||
|
let list = ref([]);
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const upOption = ref({
|
||||||
|
page: { num: 0, size: 10 },
|
||||||
|
noMoreSize: 5,
|
||||||
|
empty: { tip: '~ 空空如也 ~' },
|
||||||
|
textLoading: '加载中...',
|
||||||
|
textNoMore: '已经到底了'
|
||||||
|
});
|
||||||
|
|
||||||
|
const downOption = ref({
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
let cssFlag=ref(false);//控制样式
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
cssFlag.value = true;
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
const res = await getNoticeList(1, upOption.value.page.size);
|
||||||
|
cssFlag.value = false;
|
||||||
|
list.value = res.list;
|
||||||
|
mescroll.resetUpScroll();
|
||||||
|
},500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
mescroll.endSuccess();
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上拉加载更多
|
||||||
|
const upCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
const res = await getNoticeList(mescroll.num, mescroll.size);
|
||||||
|
if (mescroll.num === 1) {
|
||||||
|
list.value = res.list;
|
||||||
|
} else {
|
||||||
|
list.value.push(...res.list);
|
||||||
|
}
|
||||||
|
mescroll.endBySize(res.list.length, res.total);
|
||||||
|
},500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getNoticeList = (pageIndex, pageSize) => {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
let param = {
|
||||||
|
pageIndex,
|
||||||
|
pageSize
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = await noticeList(param);
|
||||||
|
resolve({
|
||||||
|
list: res.list,
|
||||||
|
total: res.totalCount
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.all-body{
|
||||||
|
position: absolute;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
top:150rpx;
|
||||||
|
height: calc(100vh - 75px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
top:120rpx;
|
||||||
|
height: calc(100vh - 64px);
|
||||||
|
/* #endif */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
:deep(.mescroll-downwarp .downwarp-progress){
|
||||||
|
border-color:#fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.mescroll-downwarp .downwarp-tip){
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
width: 750rpx;
|
||||||
|
padding: 40rpx 0 ;
|
||||||
|
margin-bottom:0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 120px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 140px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .notice-list {
|
||||||
|
display: flex;
|
||||||
|
padding: 0 30rpx 0 40rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .notice-list img {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .notice-list .notice-item {
|
||||||
|
border-bottom: 1px solid #E7E7E7;
|
||||||
|
width: 570rpx;
|
||||||
|
padding-bottom: 30rpx;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .notice-list:last-child .notice-item {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .notice-list .notice-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
width: 530rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
/* 禁止换行 */
|
||||||
|
overflow: hidden;
|
||||||
|
/* 隐藏溢出内容 */
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
/* 显示省略号 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .notice-list .notice-title.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .notice-list .notice-date {
|
||||||
|
color: #BFBFBF;
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-top: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .notice-list .notice-item .dot {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 14rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
329
src/pages/userinfo/userinfo.vue
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
|
||||||
|
<!-- 下拉刷新 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit"
|
||||||
|
:down="downOption" @down="downCallback"
|
||||||
|
:fixed="false" class="scroll-h" :style="{ paddingTop: navBarPaddingTop + 'px' }"
|
||||||
|
>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<view style="height:50rpx"></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- 头像 -->
|
||||||
|
<view class="head-pic">
|
||||||
|
<img class="pic-img" :src="'static/images/userinfo/icon-userinfo.png'" />
|
||||||
|
<view class="head-name">
|
||||||
|
<view class="nick">
|
||||||
|
<view class="nick-text">{{ userObj.name }}</view>
|
||||||
|
<img :src="`static/images/userinfo/num-${userObj.level}@2x.png`" class="level" />
|
||||||
|
</view>
|
||||||
|
<view class="dept">{{ userObj.deptName }} {{ userObj.jobName }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="head-right">
|
||||||
|
<view class="font-ruzhi">已入职{{userObj.joinDay}}天</view>
|
||||||
|
<img :src="'static/images/userinfo/icon-heart@2x.png'" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 日常 -->
|
||||||
|
<view class="backlog-bg">
|
||||||
|
<view class="backlog-b-item">
|
||||||
|
<img :src="'static/images/business/icon-rwjh.png'" />
|
||||||
|
<view class="font-title">任务计划</view>
|
||||||
|
</view>
|
||||||
|
<view class="backlog-b-item">
|
||||||
|
<img :src="'static/images/business/icon-rb.png'" />
|
||||||
|
<view class="font-title">日报</view>
|
||||||
|
</view>
|
||||||
|
<view class="backlog-b-item">
|
||||||
|
<img :src="'static/images/business/icon-sbgl.png'" />
|
||||||
|
<view class="font-title">设备管理</view>
|
||||||
|
</view>
|
||||||
|
<view class="backlog-b-item">
|
||||||
|
<img :src="'static/images/business/icon-jxgl.png'" />
|
||||||
|
<view class="font-title">绩效管理</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 头像块 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="list-item">
|
||||||
|
<img :src="'static/images/userinfo/icon-tx@2x.png'" class="l-icon" />
|
||||||
|
<text>头像</text>
|
||||||
|
<view class="list-right">
|
||||||
|
<img class="pic-img" :src="'static/images/userinfo/icon-userinfo.png'" />
|
||||||
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 登录管理,修改密码,版本更新块 -->
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="list-item item-padding">
|
||||||
|
<img :src="'static/images/userinfo/icon-dlgl@2x.png'" class="l-icon" />
|
||||||
|
<view>登录管理</view>
|
||||||
|
<view class="list-right">
|
||||||
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="item-border"></view>
|
||||||
|
<view class="list-item item-padding">
|
||||||
|
<img :src="'static/images/userinfo/icon-xgmm@2x.png'" class="l-icon" />
|
||||||
|
<view>修改密码</view>
|
||||||
|
<view class="list-right">
|
||||||
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="item-border"></view>
|
||||||
|
<view class="list-item item-padding">
|
||||||
|
<img :src="'static/images/userinfo/icon-bbgx@2x.png'" class="l-icon" />
|
||||||
|
<view class="item-text">版本更新 <view class="dot"></view></view>
|
||||||
|
<view class="list-right">
|
||||||
|
<text class="item-gray">Version 1.0.0</text>
|
||||||
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 退出登录 -->
|
||||||
|
<button type="primary" plain="true" size="small" class="logout-btn" @click="handleLoginOut">退出登录</button>
|
||||||
|
|
||||||
|
<!-- 底部加高度来避免tabbar遮挡 -->
|
||||||
|
<!-- <view class="bottom-height"></view> -->
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
// import customHeader from '@/components/customHeader.vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import { getNavBarPaddingTop } from '@/utils/system.js'
|
||||||
|
|
||||||
|
import { getUserInfo } from '@/api/auth.js'
|
||||||
|
|
||||||
|
import { useUserStore } from '@/stores/user';
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
// 1.头部导航栏
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
const downOption = ref({
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
// mescroll.resetUpScroll();
|
||||||
|
},500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
mescroll.endSuccess();
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.获取用户基本信息
|
||||||
|
let userObj = ref({});
|
||||||
|
const selectUserInfo = async ()=>{
|
||||||
|
let data = await getUserInfo({});
|
||||||
|
userObj.value = data;
|
||||||
|
}
|
||||||
|
selectUserInfo()
|
||||||
|
|
||||||
|
// 3.退出登录
|
||||||
|
const handleLoginOut = async ()=>{
|
||||||
|
userStore.logout();
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/login/login',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:calc(100vh - 30px) !important;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 30px) !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
:deep(.mescroll-upwarp){
|
||||||
|
display:none
|
||||||
|
}
|
||||||
|
.head-pic {
|
||||||
|
display: flex;
|
||||||
|
padding: 40rpx 0rpx 10rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .pic-img {
|
||||||
|
width: 110rpx;
|
||||||
|
height: 110rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .head-name {
|
||||||
|
color: #fff;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
padding: 10rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .head-name .nick {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .head-name .nick .nick-text {
|
||||||
|
padding-right: 35rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .head-name .nick .level {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 30%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 30rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .head-name .dept {
|
||||||
|
color: #94F6FF;
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-top:10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .head-right {
|
||||||
|
margin-left: auto;
|
||||||
|
background-color: #034FCC;
|
||||||
|
border-radius: 15px 0 0 15px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 24rpx;
|
||||||
|
padding: 5rpx 10rpx 5rpx 30rpx;
|
||||||
|
display: flex;
|
||||||
|
height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .head-right .font-ruzhi {
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-pic .head-right img {
|
||||||
|
display: block;
|
||||||
|
width: 28rpx;
|
||||||
|
height: 25rpx;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backlog-bg {
|
||||||
|
background: url('@/static/images/userinfo/bg-me@2x.png') no-repeat;
|
||||||
|
background-size: 730rpx 250rpx;
|
||||||
|
width: 690rpx;
|
||||||
|
height: 250rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backlog-b-item {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backlog-b-item img{
|
||||||
|
width: 90rpx;
|
||||||
|
height: 90rpx;
|
||||||
|
margin:0 auto 10rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backlog-b-item .font-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg{
|
||||||
|
width:590rpx;/*690*/
|
||||||
|
padding:30rpx 50rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
.list-item.item-padding{
|
||||||
|
padding:45rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item.item-padding:first-child{
|
||||||
|
padding-top:20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item.item-padding:last-child{
|
||||||
|
padding-bottom:20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-border{
|
||||||
|
height:1px;
|
||||||
|
background-color: #E7E7E7;
|
||||||
|
width:640rpx;
|
||||||
|
}
|
||||||
|
.list-item .l-icon{
|
||||||
|
width:46rpx;
|
||||||
|
/* height: 46rpx; */
|
||||||
|
margin-right:20rpx;
|
||||||
|
}
|
||||||
|
.list-item .list-right{
|
||||||
|
margin-left: auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.list-item .list-right .pic-img{
|
||||||
|
width:72rpx;
|
||||||
|
height: 72rpx;
|
||||||
|
margin-right:20rpx;
|
||||||
|
}
|
||||||
|
.list-item .list-right .item-gray{
|
||||||
|
color:#BFBFBF;
|
||||||
|
font-size:28rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
.list-item .item-text{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.list-item .dot{
|
||||||
|
margin-left:15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-btn{
|
||||||
|
width:360rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 75rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
background-color: #fff !important;
|
||||||
|
font-size:36rpx !important;
|
||||||
|
margin:109rpx auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
586
src/static/common.css
Normal file
@@ -0,0 +1,586 @@
|
|||||||
|
@import '@/static/font/iconfont.css';
|
||||||
|
|
||||||
|
page {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.con-body {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.con-bg {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
background: url('@/static/images/bg-Blue.png') no-repeat;
|
||||||
|
background-size: 100vw 761rpx;
|
||||||
|
width: 100vw;
|
||||||
|
height: 761rpx;
|
||||||
|
left: 0;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
background: url('@/static/images/bg-Blue.png') no-repeat;
|
||||||
|
background-size: 750rpx 761rpx;
|
||||||
|
width: 750rpx;
|
||||||
|
height: 761rpx;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -375rpx;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-height {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: 160rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: 116rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-height {
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-bottom20 {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-auto {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-bold {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-gray {
|
||||||
|
color: #919191;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 弹出提示框修改样式 begin */
|
||||||
|
.uni-modal {
|
||||||
|
border-radius: 24rpx !important;
|
||||||
|
width: 70% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-modal .uni-modal__bd {
|
||||||
|
color: #393939 !important;
|
||||||
|
font-size: 30rpx !important;
|
||||||
|
padding-top: 50rpx !important;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-modal .uni-modal__btn::after {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-modal .uni-modal__ft {
|
||||||
|
padding: 20rpx 40rpx 60rpx !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: space-between !important;
|
||||||
|
gap: 5% !important;
|
||||||
|
/* 元素间距 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-modal .uni-modal__ft::after {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-modal .uni-modal__btn {
|
||||||
|
/* flex-basis: 200rpx !important; */
|
||||||
|
border-radius: 48rpx !important;
|
||||||
|
font-size: 30rpx !important;
|
||||||
|
/* width:150rpx !important; */
|
||||||
|
height: 65rpx !important;
|
||||||
|
line-height: 60rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-modal .uni-modal__btn_default {
|
||||||
|
border: 1px solid #05A3F4 !important;
|
||||||
|
color: #05A3F4 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-modal .uni-modal__btn_primary {
|
||||||
|
/* margin-left:20rpx !important; */
|
||||||
|
background-color: #05A3F4 !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹出提示框修改样式 end */
|
||||||
|
|
||||||
|
/* 搜索框修改样式 begin */
|
||||||
|
.custom-search.uni-searchbar {
|
||||||
|
padding: 10rpx 30rpx 30rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-search .uni-searchbar__box {
|
||||||
|
height: 56rpx !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-search .uni-searchbar__text-placeholder {
|
||||||
|
color: #fff !important;
|
||||||
|
font-size: 27rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-search .uni-searchbar__box-icon-search {
|
||||||
|
padding: 0 0 0 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-search .uni-searchbar__box-icon-search .uniui-search {
|
||||||
|
color: #fff !important;
|
||||||
|
font-size: 40rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-search .uni-input-placeholder {
|
||||||
|
color: #fff !important;
|
||||||
|
font-size: 27rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-search .uni-searchbar__box-icon-clear {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .custom-search .uni-searchbar__box-icon-clear .uniui-clear{
|
||||||
|
color:#fff !important;
|
||||||
|
font-size: 40rpx !important;
|
||||||
|
} */
|
||||||
|
/* 搜索框修改样式 end */
|
||||||
|
|
||||||
|
.head-right {
|
||||||
|
font-size: 28rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:160rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height:116rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-right img {
|
||||||
|
width: 28rpx;
|
||||||
|
height: 33rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-right .uni-icons {
|
||||||
|
margin-right: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-bottom {
|
||||||
|
height: 1px;
|
||||||
|
background-color: #E7E7E7;
|
||||||
|
width: 660rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-bottom.b-width {
|
||||||
|
width: 720rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-body {
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
top: 88rpx;
|
||||||
|
height: calc(100vh - 44px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
top: 88rpx;
|
||||||
|
height: calc(100vh);
|
||||||
|
/* #endif */
|
||||||
|
overflow: hidden;
|
||||||
|
/* z-index:999; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
width: 630rpx;
|
||||||
|
/*690*/
|
||||||
|
margin: 10rpx auto 30rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title {
|
||||||
|
display: flex;
|
||||||
|
color: #333;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title text {
|
||||||
|
color: #0395E0;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title text .iconfont {
|
||||||
|
font-size: 11px !important;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title .btn-edit{
|
||||||
|
margin-left:auto;
|
||||||
|
background-color: #05A3F4;
|
||||||
|
padding:10rpx 30rpx;
|
||||||
|
color:#fff;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
font-size:28rpx;
|
||||||
|
font-weight: normal;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.white-bg .logo-list {
|
||||||
|
margin-top: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
/* 关键属性:允许换行 */
|
||||||
|
gap: 20rpx;
|
||||||
|
/* 项目间距 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .logo-list .l-l-item {
|
||||||
|
width: 140rpx;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .logo-list .l-l-item img {
|
||||||
|
width: 90rpx;
|
||||||
|
height: 90rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .logo-list .l-l-item .font-gray {
|
||||||
|
color: #333;
|
||||||
|
font-size: 13px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .logo-list .l-l-item .uni-badge--x {
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
top: -3px
|
||||||
|
}
|
||||||
|
|
||||||
|
.mar-top {
|
||||||
|
margin-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title .yellow-bg {
|
||||||
|
background-color: #FFF5DD;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: auto;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title .yellow-bg .iconfont {
|
||||||
|
font-size: 35rpx;
|
||||||
|
color: #6CBCFF;
|
||||||
|
margin-right: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title .yellow-bg .text-black {
|
||||||
|
color: #333;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title .yellow-bg .picker-icon {
|
||||||
|
color: #282728;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .w-b-title .yellow-bg .uni-input {
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-list {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-list .news-item {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #E7E7E7;
|
||||||
|
padding: 30rpx 0 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-list .news-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-list .news-item .n-i-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-list .news-item .n-i-title .n-i-date {
|
||||||
|
color: #BFBFBF;
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-top: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-list .news-item img {
|
||||||
|
width: 240rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni-button[size='mini'] {
|
||||||
|
font-size: 28rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni-button[type='primary'][plain] {
|
||||||
|
color: #05A3F4 !important;
|
||||||
|
border: 1px solid #05A3F4 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
background-color: #FF2B44;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CRM 样式 begin */
|
||||||
|
.loading-scroll .mescroll-upwarp .upwarp-progress{
|
||||||
|
border-color: #fff !important;
|
||||||
|
}
|
||||||
|
.loading-scroll .mescroll-upwarp .upwarp-tip{
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mescroll-downwarp .downwarp-progress,
|
||||||
|
.mescroll-downwarp .mescroll-rotate {
|
||||||
|
border-color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mescroll-downwarp .downwarp-tip,
|
||||||
|
.mescroll-downwarp .upwarp-tip {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list {}
|
||||||
|
|
||||||
|
.report-list .title {
|
||||||
|
color: #3384DF;
|
||||||
|
font-size: 38rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list {
|
||||||
|
padding: 20rpx 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .r-left {
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .r-name {
|
||||||
|
color: #333;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .r-gray {
|
||||||
|
color: #919191;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .r-right {
|
||||||
|
margin-left: auto;
|
||||||
|
text-align: right;
|
||||||
|
color: #919191;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .btn-orange,
|
||||||
|
.report-list .r-list .btn-pink,
|
||||||
|
.report-list .r-list .btn-gray {
|
||||||
|
background-color: #FF9638;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 10rpx 15rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .btn-orange::after,
|
||||||
|
.report-list .r-list .btn-pink::after,
|
||||||
|
.report-list .r-list .btn-gray::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .btn-pink {
|
||||||
|
background-color: #FF687A;
|
||||||
|
padding: 10rpx 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .btn-gray {
|
||||||
|
background-color: #F0F0F0;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
color: #919191;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-list .btn-blue {
|
||||||
|
background-color: #05A3F4;
|
||||||
|
padding: 10rpx 30rpx;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .uni-forms-item__label {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .f-c-right .uni-forms-item__content {
|
||||||
|
text-align: right;
|
||||||
|
color: #919191;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .f-c-right .f-c-text {
|
||||||
|
color: #919191;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .uni-forms-item {
|
||||||
|
margin-bottom: 25rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .txt-right {
|
||||||
|
padding-right: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .footer-con {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .form-con .form-texarea .is-textarea{
|
||||||
|
min-height: 230rpx;
|
||||||
|
} */
|
||||||
|
.form-con .form-picker {
|
||||||
|
border: 1px solid #E7E7E7;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
color: #919191;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .form-picker .uniui-down {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .footer-con .btn-default,
|
||||||
|
.form-con .footer-con .btn-primary {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #05A3F4;
|
||||||
|
color: #05A3F4;
|
||||||
|
border-radius: 25px;
|
||||||
|
padding: 0rpx 80rpx;
|
||||||
|
font-size: 34rpx;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .footer-con .btn-primary {
|
||||||
|
background-color: #05A3F4;
|
||||||
|
border: 1px solid #05A3F4;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0rpx 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-con .footer-con .btn-default::after,
|
||||||
|
.form-con .footer-con .btn-primary::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-table th,
|
||||||
|
.my-table td {
|
||||||
|
border: 1px solid #E9E9E9;
|
||||||
|
padding: 12rpx 10rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size:26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-table th {
|
||||||
|
background-color: #ffffff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-table tr:nth-child(even) {
|
||||||
|
background-color: #F7F7F7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-table tr:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
.my-table .tab-width100{
|
||||||
|
width:100rpx;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
.my-table .tab-width160{
|
||||||
|
width:160rpx;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
.my-table .txtLeft{
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CRM 样式 end */
|
||||||
81
src/static/font/iconfont.css
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "iconfont"; /* Project id 4386638 */
|
||||||
|
src: url('~@/static/font/iconfont.ttf?t=1703474652463') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family: "iconfont" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-phonebaocun:before {
|
||||||
|
content: "\e80b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-phoneshizhong:before {
|
||||||
|
content: "\e74f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-phonesaoyisao:before {
|
||||||
|
content: "\e891";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-qh-right:before {
|
||||||
|
content: "\e603";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-qh-right2:before {
|
||||||
|
content: "\e602";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-share:before {
|
||||||
|
content: "\ebab";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-link:before {
|
||||||
|
content: "\e63a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-up:before {
|
||||||
|
content: "\e601";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-down:before {
|
||||||
|
content: "\e671";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bonus:before {
|
||||||
|
content: "\e646";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-message:before {
|
||||||
|
content: "\e645";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-lightning:before {
|
||||||
|
content: "\e6b9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-watch1:before {
|
||||||
|
content: "\e66d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-watch:before {
|
||||||
|
content: "\e614";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-code:before {
|
||||||
|
content: "\e61e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-phone:before {
|
||||||
|
content: "\e678";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-dang:before {
|
||||||
|
content: "\e600";
|
||||||
|
}
|
||||||
|
|
||||||
BIN
src/static/font/iconfont.ttf
Normal file
BIN
src/static/images/bg-Blue-header.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/static/images/bg-Blue-header2.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
src/static/images/bg-Blue.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src/static/images/bg-main@2x.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src/static/images/bg-notice@2x.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
src/static/images/business/btn-dk.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
src/static/images/business/btn-qd.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
src/static/images/business/demo.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
src/static/images/business/icon-add.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
src/static/images/business/icon-bx.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
src/static/images/business/icon-date.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
src/static/images/business/icon-dktj.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
src/static/images/business/icon-dkxx.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
src/static/images/business/icon-gygg.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
src/static/images/business/icon-gzsq.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
src/static/images/business/icon-hkck.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
src/static/images/business/icon-hysyy.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
src/static/images/business/icon-jhck.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
src/static/images/business/icon-jxgl.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
src/static/images/business/icon-khrybg.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
src/static/images/business/icon-khrysh.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
src/static/images/business/icon-khryss.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
src/static/images/business/icon-kygy.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
src/static/images/business/icon-mbgl.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
src/static/images/business/icon-qddk.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/static/images/business/icon-rb.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
src/static/images/business/icon-rwjh.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
src/static/images/business/icon-ryxz.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
src/static/images/business/icon-sbgl.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/static/images/business/icon-schd.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/static/images/business/icon-sjcj.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
src/static/images/business/icon-xxck.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
src/static/images/business/icon-xxtj.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/static/images/business/icon-zfbg.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
src/static/images/business/icon-zfck.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
src/static/images/business/icon-zfsp.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
src/static/images/business/xxsh.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
src/static/images/captcha/1.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/static/images/captcha/1.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src/static/images/captcha/2-1.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src/static/images/captcha/2.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/static/images/captcha/3-1.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/static/images/captcha/3.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/static/images/icon-notice@2x.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src/static/images/icon.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/static/images/loading-logo.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
src/static/images/loading-txt.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
src/static/images/login-bg.png
Normal file
|
After Width: | Height: | Size: 374 KiB |
BIN
src/static/images/login-txt.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
src/static/images/notice/icon-DaiBan@2x.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
src/static/images/notice/icon-FuWu@2x.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
src/static/images/notice/icon-RiCheng@2x.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
src/static/images/notice/icon-TiXing@2x.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
src/static/images/notice/icon-TongZhi@2x.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src/static/images/notice/icon-clean@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/static/images/pic-logo.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
src/static/images/tabs/menu-business-on.png
Normal file
|
After Width: | Height: | Size: 160 B |
BIN
src/static/images/tabs/menu-business.png
Normal file
|
After Width: | Height: | Size: 160 B |