新增功能

This commit is contained in:
Your Name
2026-03-14 11:16:04 +08:00
parent eb283f008b
commit 4ddee40675
264 changed files with 5039 additions and 2813 deletions
-178
View File
@@ -1,178 +0,0 @@
# 小程序API配置说明
## 问题解决
已修复 `process is not defined` 错误。小程序环境不支持 Node.js 的 `process` 对象。
## API 基础URL 配置
### 当前配置
API 基础 URL 在 `utils/api.js` 中定义:
```javascript
const API_BASE_URL = 'http://api.zzzhengyangtang.cn'
```
### 修改 API 地址
根据你的实际后端地址修改 `TUICallKit-Vue3/utils/api.js` 中的 `API_BASE_URL`
```javascript
// 开发环境
const API_BASE_URL = 'http://localhost:8000/api'
// 生产环境
const API_BASE_URL = 'https://your-production-api.com/api'
```
## 医生API端点
### 1. 获取医生列表
```javascript
import { doctorApi } from '../utils/api'
const response = await doctorApi.getDoctorList({
page_no: 1,
page_size: 10,
keyword: '医生' // 可选
})
```
**响应格式**:
```json
{
"code": 1,
"msg": "success",
"data": {
"lists": [
{
"id": 1,
"name": "张医生",
"account": "doctor1",
"avatar": "http://example.com/avatar.jpg",
"mobile": "13800138000",
"email": "doctor@example.com",
"specialty": "医生",
"title": "医生",
"rating": "4.8"
}
],
"count": 10,
"page_no": 1,
"page_size": 10
}
}
```
### 2. 获取医生详情
```javascript
const doctor = await doctorApi.getDoctorDetail(1)
```
### 3. 获取医生排班
```javascript
const roster = await doctorApi.getDoctorRoster(1, '2024-03-11')
```
## 错误处理
API 请求会自动处理以下情况:
1. **网络错误**: 显示 "网络错误" 提示
2. **请求失败**: 显示 "获取医生列表失败" 提示
3. **登录失效**: 自动清除 token
## 首页集成
首页 (`pages/index/index.vue`) 会在加载时自动调用 `fetchDoctors()` 方法获取医生列表。
### 首页流程
1. 页面加载时调用 `onMounted()`
2. `onMounted()` 调用 `fetchDoctors()`
3. `fetchDoctors()` 调用 `doctorApi.getDoctorList()`
4. 获取成功后更新 `doctors` 数据
5. 医生卡片自动渲染
### 点击医生卡片
点击医生卡片会跳转到挂号页面:
```javascript
uni.navigateTo({
url: `/pages/order/index?doctorId=${doctor.id}&doctorName=${doctor.name}`
})
```
## 调试技巧
### 1. 查看网络请求
在小程序开发者工具中:
1. 打开 "Network" 标签
2. 查看 API 请求的 URL、参数和响应
### 2. 查看控制台日志
```javascript
console.error('请求失败:', error)
```
### 3. 测试 API
使用 Postman 或 curl 测试 API
```bash
# 获取医生列表
curl "http://localhost:8000/api/doctor/lists?page_no=1&page_size=10"
# 获取医生详情
curl "http://localhost:8000/api/doctor/detail?id=1"
# 获取医生排班
curl "http://localhost:8000/api/doctor/roster?doctor_id=1&date=2024-03-11"
```
## 常见问题
### Q: 医生列表为空?
A: 检查以下几点:
1. API 地址是否正确
2. 后端是否有医生数据(role_id = 1)
3. 医生的 disable 字段是否为 0
4. 网络连接是否正常
### Q: 头像无法显示?
A:
1. 检查 avatar URL 是否完整
2. 检查图片服务器是否可访问
3. 检查小程序是否有网络权限
### Q: 如何修改 API 地址?
A: 修改 `TUICallKit-Vue3/utils/api.js` 中的 `API_BASE_URL` 常量。
### Q: 如何添加请求头?
A: 修改 `request()` 函数中的 `header` 对象:
```javascript
header: {
'Content-Type': 'application/json',
'Authorization': token,
'Custom-Header': 'value' // 添加自定义请求头
}
```
## 相关文件
- API 服务: `TUICallKit-Vue3/utils/api.js`
- 首页组件: `TUICallKit-Vue3/pages/index/index.vue`
- 后端控制器: `server/app/api/controller/DoctorController.php`
- 后端逻辑: `server/app/api/logic/DoctorLogic.php`
-361
View File
@@ -1,361 +0,0 @@
# 小程序 API 使用指南
## 概述
小程序使用统一的 API 请求方式,通过 `main.js` 中定义的全局 `apiUrl` 方法进行请求。
## 全局 apiUrl 方法
### 定义位置
`TUICallKit-Vue3/main.js` 中定义了全局的 `apiUrl` 方法:
```javascript
function apiUrl(promise, Loading = true) {
const token = uni.getStorageSync('token')
const header = {
token: token,
'content-type': 'application/x-www-form-urlencoded',
...(promise.header || {})
}
const data = promise.data || {}
const url = baseUrl + (promise.url || '')
return new Promise((resolve, reject) => {
if (Loading) {
uni.showLoading({ title: '加载中...', mask: true })
}
uni.request({
url: url,
data: data,
timeout: 15000,
method: promise.method || 'POST',
header: header,
sslVerify: false,
success: (res) => {
const data = res.data
if (data.code === -1) {
uni.removeStorageSync('token')
}
resolve(data)
},
fail: (e) => {
reject(e)
},
complete: (e) => {
if (Loading) {
uni.hideLoading()
}
}
})
})
}
```
### 参数说明
| 参数 | 类型 | 说明 |
|------|------|------|
| promise.url | string | 请求URL(相对路径) |
| promise.method | string | 请求方法(GET/POST,默认POST |
| promise.data | object | 请求数据 |
| promise.header | object | 自定义请求头 |
| Loading | boolean | 是否显示加载中(默认true) |
## API 服务层
### 文件位置
`TUICallKit-Vue3/utils/api.js`
### 基础方法
```javascript
// GET 请求
export const get = (url, data = {}, loading = false) => {
return request(url, 'GET', data, loading)
}
// POST 请求
export const post = (url, data = {}, loading = true) => {
return request(url, 'POST', data, loading)
}
```
### 医生 API
```javascript
export const doctorApi = {
// 获取医生列表
getDoctorList: (params) => get('/api/doctor/lists', params, false),
// 获取医生详情
getDoctorDetail: (id) => get('/api/doctor/detail', { id }, false),
// 获取医生排班
getDoctorRoster: (doctorId, date) => get('/api/doctor/roster', { doctor_id: doctorId, date }, false)
}
```
## 使用示例
### 1. 在组件中使用
```vue
<script setup>
import { ref, onMounted } from 'vue'
import { doctorApi } from '../utils/api'
const doctors = ref([])
const loading = ref(false)
// 获取医生列表
const fetchDoctors = async () => {
loading.value = true
try {
const response = await doctorApi.getDoctorList({
page_no: 1,
page_size: 10
})
if (response && response.code === 1) {
doctors.value = response.data.lists || []
} else {
uni.showToast({
title: response.msg || '获取失败',
icon: 'none'
})
}
} catch (error) {
console.error('请求失败:', error)
uni.showToast({
title: '网络错误',
icon: 'none'
})
} finally {
loading.value = false
}
}
onMounted(() => {
fetchDoctors()
})
</script>
```
### 2. 创建新的 API 模块
```javascript
// utils/api.js 中添加
export const appointmentApi = {
// 获取预约列表
getAppointmentList: (params) => get('/api/appointment/lists', params, false),
// 创建预约
createAppointment: (data) => post('/api/appointment/create', data, true),
// 取消预约
cancelAppointment: (id) => post('/api/appointment/cancel', { id }, true)
}
```
### 3. 使用自定义请求头
```javascript
import { request } from '../utils/api'
// 发送带自定义请求头的请求
const response = await request(
'/api/custom/endpoint',
'POST',
{ data: 'value' },
true,
{ 'X-Custom-Header': 'custom-value' }
)
```
## 响应格式
### 成功响应
```json
{
"code": 1,
"msg": "success",
"data": {
"lists": [...],
"count": 10,
"page_no": 1,
"page_size": 10
}
}
```
### 失败响应
```json
{
"code": 0,
"msg": "错误信息"
}
```
### 登录失效
```json
{
"code": -1,
"msg": "登录已失效"
}
```
`code === -1` 时,会自动清除 token。
## 错误处理
### 自动处理
- 登录失效(code === -1):自动清除 token
- 网络错误:自动显示加载中/隐藏加载中
### 手动处理
```javascript
try {
const response = await doctorApi.getDoctorList({ page_no: 1 })
if (response.code === 1) {
// 成功处理
console.log(response.data)
} else if (response.code === -1) {
// 登录失效,跳转到登录页
uni.redirectTo({ url: '/pages/login/login' })
} else {
// 其他错误
uni.showToast({
title: response.msg || '请求失败',
icon: 'none'
})
}
} catch (error) {
// 网络错误
console.error('网络错误:', error)
uni.showToast({
title: '网络错误,请检查连接',
icon: 'none'
})
}
```
## 配置说明
### 基础 URL
`main.js` 中定义:
```javascript
var baseUrl = 'http://api.zzzhengyangtang.cn'
```
修改此值来改变 API 基础地址。
### 超时时间
`main.js` 中的 `uni.request` 中定义:
```javascript
timeout: 15000 // 15秒超时
```
### 请求头
默认请求头:
```javascript
{
token: 'user_token',
'content-type': 'application/x-www-form-urlencoded'
}
```
## 常见问题
### Q: 如何添加新的 API
A: 在 `utils/api.js` 中添加新的 API 对象:
```javascript
export const newApi = {
getList: (params) => get('/api/new/lists', params, false),
create: (data) => post('/api/new/create', data, true)
}
```
### Q: 如何修改请求头?
A: 在 `request` 函数中修改 `header` 对象,或在调用时传入自定义请求头。
### Q: 如何处理文件上传?
A: 使用 `uni.uploadFile` 而不是 `uni.request`
```javascript
export const uploadFile = (filePath, url) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: baseUrl + url,
filePath: filePath,
name: 'file',
header: {
token: uni.getStorageSync('token')
},
success: (res) => {
resolve(JSON.parse(res.data))
},
fail: (err) => {
reject(err)
}
})
})
}
```
### Q: 如何取消请求?
A: 小程序的 `uni.request` 不支持直接取消,但可以使用标志位:
```javascript
let requestAborted = false
const fetchData = async () => {
const response = await doctorApi.getDoctorList({ page_no: 1 })
if (requestAborted) {
return
}
// 处理响应
}
// 取消请求
const abortRequest = () => {
requestAborted = true
}
```
## 最佳实践
1. **统一 API 管理**:所有 API 调用都通过 `utils/api.js` 进行
2. **错误处理**:始终使用 try-catch 处理异步请求
3. **加载状态**:在请求时显示加载中,完成后隐藏
4. **响应验证**:检查 `code` 字段判断请求是否成功
5. **token 管理**:自动处理 token 过期情况
## 相关文件
- API 服务: `TUICallKit-Vue3/utils/api.js`
- 全局配置: `TUICallKit-Vue3/main.js`
- 首页示例: `TUICallKit-Vue3/pages/index/index.vue`
- API 配置: `TUICallKit-Vue3/API_CONFIG.md`
-302
View File
@@ -1,302 +0,0 @@
# 老年人友好的首页设计指南
## 设计理念
针对60岁左右的用户群体,设计简洁、清晰、易操作的界面。
### 核心原则
1. **字体大** - 所有文字都要足够大,便于阅读
2. **操作简单** - 减少复杂操作,一键直达
3. **色彩清晰** - 高对比度,清晰易辨
4. **布局简洁** - 信息不过载,重点突出
5. **反馈明确** - 每个操作都有清晰的反馈
## 页面结构
```
┌─────────────────────────────────┐
│ 养生堂 ⋯ ◯ │ <- 顶部标题栏
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ │
│ [轮播图] │
│ │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ [头像] 赵建欣 │
│ 咨询 8次 │
│ │
│ 主任医师 中医内科 │
│ │
│ ⭐ 名医中医 │
│ │
│ 👍 好评率 95% ❤️ 服务人数 256人│
│ │
│ 🌐 互联网医院执业许可 │
│ 📋 医师执业许可证 │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ [头像] 李医生 │
│ ... │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ 🏠 首页 👤 我的 │ <- 底部导航
└─────────────────────────────────┘
```
## 字体规范
### 字体大小
- **顶部标题**: 36rpx (大标题,易识别)
- **医生名字**: 32rpx (重要信息)
- **职位/科室**: 24rpx (次要信息)
- **其他文字**: 22-24rpx (保证可读性)
- **底部导航**: 24rpx (便于点击)
### 字体权重
- **标题**: 加粗 (700)
- **重要信息**: 加粗 (600)
- **正常文字**: 正常 (400)
## 色彩方案
### 主色系
- **绿色**: #4CAF50 - 健康、生命力
- **浅绿**: #E8F5E9 - 背景色
- **黄色**: #FFF9C4 - 强调色
- **灰色**: #f5f5f5 - 页面背景
### 文字色
- **主文字**: #333 - 深灰色,高对比度
- **次文字**: #666 - 中灰色
- **辅助**: #999 - 浅灰色
## 组件设计
### 1. 顶部标题栏
```scss
.header {
padding: 24rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.header-title {
font-size: 36rpx;
font-weight: bold;
}
.icon-btn {
width: 50rpx;
height: 50rpx;
font-size: 32rpx;
border-radius: 50%;
}
```
- 标题: 36rpx,加粗
- 按钮: 50x50rpx,便于点击
- 高对比度
### 2. 轮播图
```scss
.banner {
height: 300rpx;
}
```
- 高度: 300rpx
- 自动轮播,5秒切换
- 圆角: 12rpx
- 阴影: 0 2rpx 8rpx
### 3. 医生卡片
```scss
.doctor-card {
background: #fff;
border-radius: 12rpx;
padding: 24rpx;
margin-bottom: 20rpx;
}
```
- 白色背景,清晰易读
- 内边距: 24rpx (充足的空间)
- 圆角: 12rpx
- 阴影: 0 2rpx 8rpx
### 4. 医生头部
```
[头像] 医生名字 (32rpx)
咨询 8次 (24rpx, 绿色)
```
- 头像: 100x100rpx
- 名字: 32rpx,加粗
- 描述: 24rpx,绿色
### 5. 医生标签
```
主任医师 中医内科
```
- 绿色背景,绿色文字
- 字体: 24rpx
- 圆角: 20rpx
- 高对比度
### 6. 专家标签
```
⭐ 名医中医
```
- 黄色背景
- 字体: 22rpx
- 圆角: 16rpx
### 7. 评分和服务
```
┌──────────────┬──────────────┐
│ 👍 好评率 │ ❤️ 服务人数 │
│ 95% │ 256人 │
└──────────────┴──────────────┘
```
- 两列布局
- 绿色背景
- 字体: 28rpx (数值)22rpx (标签)
- 图标: 32rpx
### 8. 资质信息
```
🌐 互联网医院执业许可
📋 医师执业许可证
```
- 列表展示
- 字体: 22rpx
- 图标: 24rpx
### 9. 底部导航
```
🏠 首页 👤 我的
```
- 固定底部
- 图标: 36-40rpx
- 文字: 24rpx
- 高对比度
## 交互设计
### 点击区域
- **最小点击区域**: 44x44rpx
- **医生卡片**: 整个卡片可点击
- **底部导航**: 每个导航项 >= 60rpx
### 反馈效果
- **卡片按下**: 阴影增强
- **按钮按下**: 背景变深
- **导航切换**: 颜色和大小变化
### 动画
- **过渡时间**: 300ms
- **轮播**: 5秒自动切换
- **缓动函数**: ease
## 易用性设计
### 1. 大字体
- 所有文字 >= 22rpx
- 标题 >= 32rpx
- 便于老年人阅读
### 2. 高对比度
- 文字和背景对比度 >= 4.5:1
- 清晰易辨
### 3. 简单操作
- 一键咨询
- 直接进入医生详情
- 无复杂交互
### 4. 清晰反馈
- 每个操作都有视觉反馈
- 按下时有阴影变化
- 导航切换有颜色变化
### 5. 充足空间
- 卡片内边距: 24rpx
- 元素间距: 16-20rpx
- 不拥挤
## 响应式设计
### 使用 rpx 单位
- 自动适配不同屏幕
- 1rpx = 0.5px (375px 宽度)
### 布局适配
- 医生卡片宽度 100%
- 自动适应屏幕宽度
- 文字自动换行
## 性能优化
- 使用 CSS 动画
- 图片自动缩放
- 减少重排和重绘
## 无障碍设计
- 足够的色彩对比度
- 清晰的文字标签
- 合理的点击区域
- 支持屏幕阅读器
## 数据流
```
页面加载
调用 fetchDoctors()
获取医生列表
处理数据
渲染医生卡片
```
## API 集成
### 获取医生列表
```javascript
const response = await proxy.apiUrl({
url: '/api/doctor/lists',
method: 'GET',
data: {
page_no: 1,
page_size: 10
}
})
```
## 点击事件
### 医生卡片点击
```javascript
selectDoctor(doctor) {
uni.navigateTo({
url: `/pages/order/index?doctorId=${doctor.id}&doctorName=${doctor.name}`
})
}
```
## 总结
这个设计方案特点:
- ✅ 字体大,易于阅读
- ✅ 操作简单,一键直达
- ✅ 色彩清晰,高对比度
- ✅ 布局简洁,信息清晰
- ✅ 反馈明确,易于理解
- ✅ 完全适合60岁左右的用户
整个页面设计充分考虑了老年人的使用习惯和需求,提供了友好、易用的医疗服务体验。
-250
View File
@@ -1,250 +0,0 @@
# 全局属性使用说明
## 概述
小程序通过 `main.js` 中的 `app.config.globalProperties` 定义全局属性,包括 `$url``apiUrl` 方法。
## 全局属性定义
### 在 main.js 中
```javascript
// Vue3 部分
export function createApp() {
const app = createSSRApp(App)
// 定义全局 baseUrl
app.config.globalProperties.$url = baseUrl
// 定义全局 apiUrl 方法
app.config.globalProperties.apiUrl = apiUrl
return {
app
}
}
```
### 全局属性列表
| 属性名 | 类型 | 说明 |
|--------|------|------|
| `$url` | string | API 基础 URL,默认值:`http://api.zzzhengyangtang.cn` |
| `apiUrl` | function | API 请求方法 |
## 在 API 服务中使用
### 获取全局属性
```javascript
import { getCurrentInstance } from 'vue'
const getGlobalProperties = () => {
try {
const instance = getCurrentInstance()
if (instance) {
return instance.appContext.config.globalProperties
}
} catch (e) {
console.warn('无法获取 getCurrentInstance')
}
return {}
}
// 使用
const globalProps = getGlobalProperties()
const baseUrl = globalProps.$url
const apiUrl = globalProps.apiUrl
```
### 在 request 函数中使用
```javascript
export const request = (url, method = 'POST', data = {}, loading = true) => {
// 获取全局属性
const globalProps = getGlobalProperties()
const apiUrl = globalProps.apiUrl
const baseUrl = globalProps.$url || 'http://api.zzzhengyangtang.cn'
if (!apiUrl) {
// 降级方案:直接使用 uni.request
return new Promise((resolve, reject) => {
uni.request({
url: `${baseUrl}${url}`,
method,
data,
// ...
})
})
}
// 使用全局 apiUrl 方法
return apiUrl({
url,
method,
data,
header: {
'content-type': 'application/x-www-form-urlencoded'
}
}, loading)
}
```
## 在组件中使用
### 方式1:通过 getCurrentInstance
```vue
<script setup>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const baseUrl = instance.appContext.config.globalProperties.$url
const apiUrl = instance.appContext.config.globalProperties.apiUrl
console.log('Base URL:', baseUrl)
</script>
```
### 方式2:通过 thisVue2 风格)
```vue
<script>
export default {
methods: {
getBaseUrl() {
return this.$url
},
async fetchData() {
const response = await this.apiUrl({
url: '/api/data',
method: 'GET'
})
console.log(response)
}
}
}
</script>
```
### 方式3:通过 inject(推荐)
```vue
<script setup>
import { inject } from 'vue'
// 在 main.js 中提供
// app.provide('$url', baseUrl)
// app.provide('apiUrl', apiUrl)
const baseUrl = inject('$url')
const apiUrl = inject('apiUrl')
</script>
```
## 修改全局属性
### 修改 baseUrl
编辑 `TUICallKit-Vue3/main.js`
```javascript
var baseUrl = 'http://your-api-domain/api'
```
### 修改 apiUrl 方法
编辑 `TUICallKit-Vue3/main.js` 中的 `apiUrl` 函数。
## 全局属性的生命周期
1. **初始化**:在 `main.js` 中通过 `app.config.globalProperties` 定义
2. **可用**:应用创建后,所有组件都可以访问
3. **销毁**:应用销毁时自动清理
## 最佳实践
### 1. 统一管理全局属性
`main.js` 中集中定义所有全局属性:
```javascript
// 定义全局属性对象
const globalConfig = {
$url: baseUrl,
apiUrl: apiUrl,
$appName: '医疗小程序',
$version: '1.0.0'
}
// 批量注册
Object.keys(globalConfig).forEach(key => {
app.config.globalProperties[key] = globalConfig[key]
})
```
### 2. 创建辅助函数
```javascript
// utils/global.js
import { getCurrentInstance } from 'vue'
export const useGlobal = () => {
const instance = getCurrentInstance()
const globalProps = instance.appContext.config.globalProperties
return {
baseUrl: globalProps.$url,
apiUrl: globalProps.apiUrl,
appName: globalProps.$appName,
version: globalProps.$version
}
}
```
### 3. 在组件中使用
```vue
<script setup>
import { useGlobal } from '@/utils/global'
const { baseUrl, apiUrl } = useGlobal()
console.log('Base URL:', baseUrl)
</script>
```
## 常见问题
### Q: 如何在非组件中使用全局属性?
A: 在 API 服务中使用 `getCurrentInstance()` 获取全局属性。
### Q: 如何动态修改全局属性?
A: 直接修改 `app.config.globalProperties` 中的值:
```javascript
const instance = getCurrentInstance()
instance.appContext.config.globalProperties.$url = 'http://new-url'
```
### Q: 全局属性和 provide/inject 的区别?
A:
- 全局属性:所有组件都可以访问,通过 `this.$property``getCurrentInstance()` 获取
- provide/inject:父组件提供,子组件注入,更灵活但需要显式提供
### Q: 如何在 Composition API 中使用全局属性?
A: 使用 `getCurrentInstance()` 获取实例,然后访问 `appContext.config.globalProperties`
## 相关文件
- 全局配置: `TUICallKit-Vue3/main.js`
- API 服务: `TUICallKit-Vue3/utils/api.js`
- 全局工具: `TUICallKit-Vue3/utils/global.js`(可选)
## 总结
通过 `app.config.globalProperties` 定义的全局属性可以在整个应用中访问,是管理全局配置和方法的最佳方式。
-309
View File
@@ -1,309 +0,0 @@
# 小程序 API 集成总结
## 核心架构
```
main.js (全局配置)
├── $url: 'http://api.zzzhengyangtang.cn'
├── apiUrl: function(promise, loading)
└── app.config.globalProperties
utils/global.js (全局工具)
├── getGlobalProperties()
├── getBaseUrl()
├── getApiUrl()
├── useGlobal()
└── getFullUrl()
utils/api.js (API 服务)
├── request(url, method, data, loading)
├── get(url, data, loading)
├── post(url, data, loading)
└── doctorApi { getDoctorList, getDoctorDetail, getDoctorRoster }
pages/index/index.vue (首页)
└── fetchDoctors() → doctorApi.getDoctorList()
```
## 文件说明
### 1. main.js - 全局配置
**定义全局属性**:
```javascript
app.config.globalProperties.$url = baseUrl
app.config.globalProperties.apiUrl = apiUrl
```
**特点**:
- 定义 API 基础 URL
- 定义 apiUrl 方法(处理 token、加载中、登录失效等)
- 支持 Vue2 和 Vue3
### 2. utils/global.js - 全局工具
**提供的函数**:
- `getGlobalProperties()` - 获取全局属性对象
- `getBaseUrl()` - 获取 API 基础 URL
- `getApiUrl()` - 获取 apiUrl 方法
- `useGlobal()` - Composition API Hook
- `getFullUrl(path)` - 获取完整 URL
- `setGlobalProperty(key, value)` - 设置全局属性
- `getGlobalProperty(key, defaultValue)` - 获取特定全局属性
**使用示例**:
```javascript
import { useGlobal, getBaseUrl } from '@/utils/global'
const { baseUrl, apiUrl } = useGlobal()
const url = getBaseUrl()
```
### 3. utils/api.js - API 服务
**提供的方法**:
- `request(url, method, data, loading)` - 基础请求方法
- `get(url, data, loading)` - GET 请求
- `post(url, data, loading)` - POST 请求
- `doctorApi` - 医生相关 API
**医生 API**:
```javascript
doctorApi.getDoctorList(params) // 获取医生列表
doctorApi.getDoctorDetail(id) // 获取医生详情
doctorApi.getDoctorRoster(id, date) // 获取医生排班
```
**特点**:
- 自动使用全局 `$url``apiUrl`
- 降级方案:当全局方法不可用时,直接使用 `uni.request`
- 自动处理 token 和请求头
### 4. pages/index/index.vue - 首页
**功能**:
- 展示古典卷轴风格幻灯片
- 动态加载医生列表
- 医生卡片点击跳转
**流程**:
```
onMounted()
fetchDoctors()
doctorApi.getDoctorList()
request() → apiUrl() → uni.request()
更新 doctors 数据
医生卡片渲染
```
## 使用流程
### 1. 在组件中使用 API
```vue
<script setup>
import { ref, onMounted } from 'vue'
import { doctorApi } from '../utils/api'
const doctors = ref([])
const fetchDoctors = async () => {
try {
const response = await doctorApi.getDoctorList({
page_no: 1,
page_size: 10
})
if (response.code === 1) {
doctors.value = response.data.lists || []
} else {
uni.showToast({
title: response.msg || '获取失败',
icon: 'none'
})
}
} catch (error) {
console.error('请求失败:', error)
}
}
onMounted(() => {
fetchDoctors()
})
</script>
```
### 2. 使用全局工具
```vue
<script setup>
import { useGlobal } from '@/utils/global'
const { baseUrl, apiUrl } = useGlobal()
console.log('Base URL:', baseUrl)
</script>
```
### 3. 添加新的 API
`utils/api.js` 中添加:
```javascript
export const appointmentApi = {
getList: (params) => get('/api/appointment/lists', params, false),
create: (data) => post('/api/appointment/create', data, true),
cancel: (id) => post('/api/appointment/cancel', { id }, true)
}
```
## 请求流程详解
### 正常流程
```
组件调用 doctorApi.getDoctorList()
调用 get('/api/doctor/lists', params, false)
调用 request('/api/doctor/lists', 'GET', params, false)
获取全局属性 ($url, apiUrl)
调用 apiUrl({ url, method, data, header }, loading)
main.js 中的 apiUrl 方法处理
获取 token,合并请求头
调用 uni.request()
返回响应数据
检查 code 字段
├─ code === 1: 成功,返回数据
├─ code === -1: 登录失效,清除 token
└─ code === 0: 失败,返回错误信息
```
### 降级流程
当全局 `apiUrl` 不可用时:
```
request() 检查 apiUrl 是否存在
apiUrl 不存在
使用降级方案:直接调用 uni.request()
获取 token,构建完整 URL
调用 uni.request()
返回响应数据
```
## 配置修改
### 修改 API 基础 URL
编辑 `main.js`
```javascript
var baseUrl = 'http://your-api-domain/api'
```
### 修改超时时间
编辑 `main.js` 中的 `uni.request`
```javascript
timeout: 20000 // 改为 20 秒
```
### 修改请求头
编辑 `main.js` 中的 `header` 对象:
```javascript
const header = {
token: token,
'content-type': 'application/x-www-form-urlencoded',
'X-Custom-Header': 'custom-value'
}
```
## 错误处理
### 自动处理
1. **登录失效** (code === -1)
- 自动清除 token
- 可选:跳转到登录页
2. **网络错误**
- 自动显示/隐藏加载中
- 返回错误信息
### 手动处理
```javascript
try {
const response = await doctorApi.getDoctorList({ page_no: 1 })
if (response.code === 1) {
// 成功
console.log(response.data)
} else if (response.code === -1) {
// 登录失效
uni.redirectTo({ url: '/pages/login/login' })
} else {
// 其他错误
uni.showToast({
title: response.msg || '请求失败',
icon: 'none'
})
}
} catch (error) {
// 网络错误
console.error('网络错误:', error)
}
```
## 最佳实践
1. **统一 API 管理**:所有 API 调用都通过 `utils/api.js`
2. **错误处理**:始终使用 try-catch 处理异步请求
3. **加载状态**:在请求时显示加载中,完成后隐藏
4. **响应验证**:检查 `code` 字段判断请求是否成功
5. **token 管理**:自动处理 token 过期情况
6. **全局属性**:使用 `utils/global.js` 中的工具函数访问全局属性
## 相关文件
- 全局配置: `TUICallKit-Vue3/main.js`
- 全局工具: `TUICallKit-Vue3/utils/global.js`
- API 服务: `TUICallKit-Vue3/utils/api.js`
- 首页组件: `TUICallKit-Vue3/pages/index/index.vue`
- 全局属性说明: `TUICallKit-Vue3/GLOBAL_PROPERTIES_USAGE.md`
- API 使用指南: `TUICallKit-Vue3/API_USAGE_GUIDE.md`
- API 配置说明: `TUICallKit-Vue3/API_CONFIG.md`
## 总结
已完成小程序与后端 API 的完整集成:
1. ✅ 全局配置管理(main.js
2. ✅ 全局工具函数(utils/global.js
3. ✅ API 服务层封装(utils/api.js
4. ✅ 首页医生列表展示(pages/index/index.vue
5. ✅ 完整的错误处理和加载状态
6. ✅ 详细的文档和使用指南
小程序现在可以正常调用后端 API 获取医生列表,并且所有 API 请求都使用 `main.js` 中定义的全局 `$url``apiUrl` 方法。
-290
View File
@@ -1,290 +0,0 @@
# 现代中医医院首页设计指南
## 设计理念
采用现代医疗应用的设计风格,结合中医特色,为60岁左右的用户提供专业、易用的医疗服务体验。
## 页面结构
```
┌─────────────────────────────────┐
│ 成都双流蜀养堂互联网医院 ⋯ ◯ │ <- 顶部信息栏
│ 📍 郑州市金水区 │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ 🔍 输入科室、疾病、医生搜索 搜索 │ <- 搜索栏
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ [轮播图] │ <- 轮播图
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ 问诊服务 │
├─────────────────────────────────┤
│ 专家问诊 │ 健康咨询 │ 快速问诊 │ <- 服务卡片
│ 去找专家 │ 前往咨询 │ 前往问诊 │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ 特色专科医师 更多 > │
├─────────────────────────────────┤
│ [头像] [头像] [头像] [头像] │ <- 医生横向滚动
│ 赵建欣 雷惧昱 稳骨 ... │
│ 主任医师 主治医师 主治医师 │
│ 内科 内科 内科 │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ 🏠 首页 📢 消息 👤 我的 │ <- 底部导航
└─────────────────────────────────┘
```
## 色彩方案
### 主色系
- **棕色**: #8B6F47 - 中医传统色
- **绿色**: #4CAF50 - 健康、生命力
- **背景**: #f5f5f5 - 页面背景
- **卡片**: #fff - 内容卡片
### 服务卡片色
- **专家问诊**: 橙色系 (#FFF3E0 - #FFE0B2)
- **健康咨询**: 绿色系 (#E8F5E9 - #C8E6C9)
- **快速问诊**: 紫色系 (#F3E5F5 - #E1BEE7)
## 组件设计
### 1. 顶部信息栏
```scss
.top-bar {
background: linear-gradient(135deg, #8B6F47 0%, #A0826D 100%);
padding: 16rpx 20rpx;
display: flex;
justify-content: space-between;
}
```
- 棕色渐变背景
- 显示医院名称和位置
- 右侧显示菜单和设置按钮
- 高度: 60rpx
### 2. 搜索栏
```scss
.search-box {
display: flex;
align-items: center;
background: #f5f5f5;
border-radius: 24rpx;
padding: 12rpx 16rpx;
}
.search-btn {
background: #4CAF50;
color: #fff;
padding: 8rpx 16rpx;
border-radius: 16rpx;
}
```
- 灰色背景,圆角搜索框
- 绿色搜索按钮
- 支持输入科室、疾病、医生
### 3. 轮播图
```scss
.banner {
height: 200rpx;
}
```
- 高度: 200rpx
- 自动轮播,5秒切换
- 圆角: 12rpx
- 阴影: 0 2rpx 8rpx
### 4. 问诊服务卡片
```scss
.service-card {
border-radius: 12rpx;
padding: 16rpx;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.service-1 { background: linear-gradient(135deg, #FFF3E0 0%, #FFE0B2 100%); }
.service-2 { background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%); }
.service-3 { background: linear-gradient(135deg, #F3E5F5 0%, #E1BEE7 100%); }
```
- 3 列网格布局
- 渐变背景
- 标题 + 描述 + 按钮
- 按下有缩放效果
### 5. 医生卡片
```scss
.doctor-card {
flex-shrink: 0;
width: 120rpx;
background: #f9f9f9;
border-radius: 12rpx;
padding: 12rpx;
text-align: center;
}
.doctor-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 8rpx;
}
```
- 横向滚动布局
- 宽度: 120rpx
- 头像: 80x80rpx
- 显示名字、职位、科室
### 6. 底部导航
```scss
.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-around;
padding: 12rpx 0 16rpx 0;
}
```
- 固定底部
- 3 个导航项
- 图标 + 文字
- 高度: 80rpx
## 字体规范
### 字体大小
- **医院名称**: 22rpx
- **服务标题**: 24rpx
- **医生名字**: 22rpx
- **职位/科室**: 18rpx
- **搜索框**: 24rpx
- **按钮**: 18-22rpx
### 字体权重
- **标题**: 加粗 (600-700)
- **重要信息**: 加粗 (600)
- **正常文字**: 正常 (400)
## 间距规范
- **页面外边距**: 20rpx
- **卡片内边距**: 12-16rpx
- **元素间距**: 8-12rpx
- **底部空间**: 100rpx (留给导航)
## 圆角规范
- **卡片**: 12rpx
- **头像**: 8rpx
- **按钮**: 16-24rpx
- **搜索框**: 24rpx
## 交互设计
### 轮播图
- 自动轮播,5秒切换
- 支持手动滑动
- 底部指示器
### 服务卡片
- 点击进入对应服务
- 按下有缩放效果 (scale 0.95)
- 300ms 过渡动画
### 医生卡片
- 横向滚动
- 点击进入医生详情
- 按下有阴影效果
### 导航切换
- 点击切换导航
- 颜色和大小变化
- 300ms 过渡动画
## 响应式设计
### 使用 rpx 单位
- 自动适配不同屏幕
- 1rpx = 0.5px (375px 宽度)
### 布局适配
- 服务卡片 3 列
- 医生卡片横向滚动
- 自动适应屏幕宽度
## 性能优化
- 使用 CSS 动画
- 图片自动缩放
- 减少重排和重绘
- 支持图片懒加载
## 无障碍设计
- 足够的色彩对比度
- 清晰的文字标签
- 合理的点击区域 (最小 44x44rpx)
- 支持屏幕阅读器
## 数据流
```
页面加载
调用 fetchDoctors()
获取医生列表
处理数据
渲染医生卡片
```
## API 集成
### 获取医生列表
```javascript
const response = await proxy.apiUrl({
url: '/api/doctor/lists',
method: 'GET',
data: {
page_no: 1,
page_size: 10
}
})
```
## 点击事件
### 医生卡片点击
```javascript
selectDoctor(doctor) {
uni.navigateTo({
url: `/pages/order/index?doctorId=${doctor.id}&doctorName=${doctor.name}`
})
}
```
## 总结
这个设计方案特点:
- ✅ 现代医疗应用风格
- ✅ 中医特色色彩搭配
- ✅ 清晰的信息层级
- ✅ 多种问诊服务选择
- ✅ 医生横向滚动展示
- ✅ 易用的导航设计
- ✅ 适合60岁左右的用户
整个页面设计专业、现代、易用,为用户提供了多种医疗服务选择和便捷的医生查询体验。
-252
View File
@@ -1,252 +0,0 @@
# 中医医院小程序首页 - 简化设计
## 页面结构
```
┌─────────────────────────────────┐
│ 中医医院 │ <- 顶部导航栏
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ │
│ [轮播图片 1] │
│ 中医药文化 │
│ 传承千年中医精粹,守护您的健康 │
│ │
│ ● ○ ○ │ <- 指示器
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ 名医推荐 │
├─────────────────────────────────┤
│ ┌─────────────────────────────┐ │
│ │ [头像] 张医生 [咨询] │ │
│ │ 专家 主任医师 │ │
│ │ 中医内科 │ │
│ │ ★★★★★ 4.9 │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ [头像] 李医生 [咨询] │ │
│ │ 副主任医师 │ │
│ │ 中医妇科 │ │
│ │ ★★★★★ 4.8 │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ [头像] 王医生 [咨询] │ │
│ │ 主治医师 │ │
│ │ 中医儿科 │ │
│ │ ★★★★★ 4.7 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────┘
```
## 设计规范
### 色彩方案
- **主色**: `#8B6914` (棕色) - 中医传统色
- **辅助色**: `#A0826D` (浅棕) - 渐变用
- **强调色**: `#FFB800` (金色) - 星级评分
- **背景**: `#f8f8f8` (浅灰)
- **卡片**: `#fff` (白色)
- **文字**: `#333` (深灰)
### 字体规范
- **标题**: 32rpx, 加粗
- **医生名字**: 28rpx, 加粗
- **职位/科室**: 22rpx, 正常
- **评分**: 20rpx, 正常
### 间距规范
- **页面外边距**: 20rpx
- **卡片内边距**: 16rpx
- **元素间距**: 4-8rpx
### 圆角规范
- **卡片**: 12rpx
- **头像**: 8rpx
- **按钮**: 20rpx
## 组件详解
### 1. 顶部导航栏
```scss
.header {
background: linear-gradient(135deg, #8B6914 0%, #A0826D 100%);
padding: 20rpx 30rpx;
color: #fff;
position: sticky;
top: 0;
z-index: 100;
}
```
- 固定顶部,棕色渐变背景
- 显示医院名称
- 高度: 60rpx
### 2. 轮播图
```scss
.banner {
height: 320rpx;
}
.banner-overlay {
background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
padding: 40rpx 30rpx;
}
```
- 高度: 320rpx
- 自动轮播,5秒切换
- 底部显示标题和描述
- 使用渐变遮罩
### 3. 医生卡片
```scss
.doctor-item {
display: flex;
gap: 16rpx;
padding: 16rpx;
background: #f9f9f9;
border-radius: 12rpx;
border: 1rpx solid #f0f0f0;
}
```
- 左侧: 头像 (100x100rpx) + 专家标签
- 中间: 医生信息 (名字、职位、科室、评分)
- 右侧: 咨询按钮
- 按下有反馈效果
### 4. 医生信息
```
医生名字 (28rpx, 加粗)
职位 (22rpx, 棕色)
科室 (20rpx, 灰色)
★★★★★ 4.9 (20rpx, 金色)
```
### 5. 咨询按钮
```scss
.consult-btn {
background: #8B6914;
color: #fff;
padding: 12rpx 20rpx;
border-radius: 20rpx;
font-size: 22rpx;
}
```
- 棕色背景,白色文字
- 圆角按钮
- 点击跳转到挂号页面
## 交互设计
### 轮播图
- 自动轮播,5秒切换一次
- 支持手动滑动
- 显示指示器点
### 医生卡片
- 点击整个卡片进入医生详情
- 按下时有缩放和阴影效果
- 咨询按钮点击进入挂号页面
### 按钮反馈
- 按下时背景变深
- 有 300ms 过渡动画
- 提供视觉反馈
## 响应式设计
### 使用 rpx 单位
- 1rpx = 0.5px (在 375px 宽度下)
- 自动适配不同屏幕尺寸
- 无需手动计算
### 布局适配
- 医生卡片使用 flex 布局
- 自动适应屏幕宽度
- 文字自动换行
## 性能优化
### 图片优化
- 使用 `mode="aspectFill"` 保持宽高比
- 图片自动缩放
- 支持懒加载
### 动画优化
- 使用 CSS 过渡而非 JS 动画
- 轮播使用原生 swiper 组件
- 减少重排和重绘
## 数据流
```
页面加载
调用 fetchDoctors()
调用 proxy.apiUrl() 获取医生列表
处理响应数据
添加 isExpert 标记
渲染医生卡片
```
## API 集成
### 获取医生列表
```javascript
const response = await proxy.apiUrl({
url: '/api/doctor/lists',
method: 'GET',
data: {
page_no: 1,
page_size: 10
}
})
```
### 响应格式
```json
{
"code": 1,
"msg": "success",
"data": {
"lists": [
{
"id": 1,
"name": "张医生",
"title": "主任医师",
"specialty": "中医内科",
"avatar": "http://...",
"rating": "4.9"
}
]
}
}
```
## 点击事件
### 医生卡片点击
```javascript
selectDoctor(doctor) {
uni.navigateTo({
url: `/pages/order/index?doctorId=${doctor.id}&doctorName=${doctor.name}`
})
}
```
## 总结
这个简化设计包含:
- ✅ 专业的顶部导航栏
- ✅ 吸引人的轮播图
- ✅ 清晰的医生列表
- ✅ 便捷的咨询按钮
- ✅ 中医风格的色彩方案
- ✅ 流畅的交互体验
整个页面简洁明了,重点突出,用户可以快速找到想要的医生并进行咨询。
-308
View File
@@ -1,308 +0,0 @@
# 中医风格首页设计指南
## 设计理念
采用绿色系中医风格,结合卡片式布局,营造专业、温和、信任的医疗氛围。
## 页面结构
```
┌─────────────────────────────────┐
│ 背景装饰(绿色渐变) │
│ │
│ ┌─────────────────────────────┐│
│ │ 轮播图 ││
│ │ ● ○ ○ ││
│ └─────────────────────────────┘│
│ │
│ ┌─────────────────────────────┐│
│ │ [头像] 赵建欣 咨询 > ││
│ │ 主任医师 ││
│ │ 中医内科 ││
│ │ ││
│ │ ⭐ 名医中医 ││
│ │ ││
│ │ 👍 好评率 95% ❤️ 服务人数 ││
│ │ ││
│ │ 🌐 互联网医院执业许可 ││
│ │ 📋 医师执业许可证 ││
│ └─────────────────────────────┘│
│ │
│ ┌─────────────────────────────┐│
│ │ [头像] 李医生 咨询 > ││
│ │ ... ││
│ └─────────────────────────────┘│
└─────────────────────────────────┘
```
## 色彩方案
### 主色系
- **主绿色**: `#4CAF50` - 中医健康、生命力
- **浅绿色**: `#81C784` - 柔和、温暖
- **背景绿**: `#E8F5E9` - 清爽、舒适
- **浅背景**: `#F1F8F6` - 卡片背景
### 辅助色
- **金色**: `#FFB800` - 强调、重要
- **黄色**: `#FFF9C4` - 标签背景
- **文字**: `#333` - 主文字
- **辅助**: `#999` - 次要文字
## 组件设计
### 1. 背景装饰
```scss
.bg-decoration {
background: linear-gradient(135deg, rgba(76, 175, 80, 0.1) 0%, rgba(129, 199, 132, 0.05) 100%);
position: fixed;
top: 0;
height: 400rpx;
}
```
- 固定背景,绿色渐变
- 营造整体氛围
- 不影响内容交互
### 2. 轮播图
```scss
.banner-section {
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(76, 175, 80, 0.15);
}
.banner {
height: 280rpx;
}
```
- 高度: 280rpx
- 圆角: 16rpx
- 绿色阴影
- 自动轮播,5秒切换
- 底部指示器
### 3. 医生卡片
```scss
.doctor-card {
background: #fff;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(76, 175, 80, 0.1);
border: 1rpx solid rgba(76, 175, 80, 0.08);
}
```
- 白色背景,绿色阴影
- 圆角: 16rpx
- 内边距: 20rpx
- 按下有上浮效果
### 4. 医生头部
```
[头像] 医生名字
咨询 >
```
- 左侧: 80x80rpx 头像
- 右侧: 名字 + 咨询按钮
- 头像圆角: 12rpx
### 5. 医生详情
```
┌──────────────┬──────────────┐
│ 主任医师 │ 中医内科 │
└──────────────┴──────────────┘
```
- 两个标签,绿色背景
- 圆角: 20rpx
- 字体: 20rpx
### 6. 医生标签
```
⭐ 名医中医
```
- 黄色背景
- 圆角: 16rpx
- 显示医生特殊身份
### 7. 医生评分
```
┌──────────────┬──────────────┐
│ 👍 好评率 │ ❤️ 服务人数 │
│ 95% │ 256人 │
└──────────────┴──────────────┘
```
- 两列布局
- 绿色背景
- 显示关键指标
### 8. 医生资质
```
🌐 互联网医院执业许可
📋 医师执业许可证
```
- 列表展示
- 图标 + 文字
- 灰色文字
## 交互设计
### 轮播图
- 自动轮播,5秒切换
- 支持手动滑动
- 底部指示器显示当前位置
- 指示器动画: 圆形 → 胶囊形
### 医生卡片
- 点击整个卡片进入医生详情
- 按下时上浮 2rpx
- 阴影增强
- 300ms 过渡动画
### 咨询按钮
- 绿色文字,表示可点击
- 点击进入挂号页面
- 带有 ">" 箭头提示
## 响应式设计
### 使用 rpx 单位
- 自动适配不同屏幕
- 1rpx = 0.5px (375px 宽度)
### 布局适配
- 医生卡片宽度 100%
- 自动适应屏幕宽度
- 文字自动换行
## 动画效果
### 轮播指示器
```scss
.dot {
transition: all 0.3s ease;
&.active {
width: 24rpx;
border-radius: 4rpx;
}
}
```
- 圆形 → 胶囊形
- 300ms 过渡
### 卡片交互
```scss
.doctor-card {
transition: all 0.3s ease;
&:active {
transform: translateY(-2rpx);
box-shadow: 0 4rpx 16rpx rgba(76, 175, 80, 0.15);
}
}
```
- 上浮 2rpx
- 阴影增强
- 300ms 过渡
## 阴影规范
- **轻**: `0 2rpx 8rpx rgba(76, 175, 80, 0.1)`
- **中**: `0 4rpx 12rpx rgba(76, 175, 80, 0.15)`
- **重**: `0 4rpx 16rpx rgba(76, 175, 80, 0.15)`
## 字体规范
- **医生名字**: 28rpx, 加粗
- **职位/科室**: 20rpx, 正常
- **咨询按钮**: 22rpx, 加粗
- **标签文字**: 18rpx, 正常
- **评分数值**: 22rpx, 加粗
- **资质文字**: 18rpx, 正常
## 间距规范
- **页面外边距**: 20rpx
- **卡片内边距**: 20rpx
- **元素间距**: 8-16rpx
- **底部空间**: 20rpx
## 圆角规范
- **卡片**: 16rpx
- **头像**: 12rpx
- **标签**: 16-20rpx
- **小元素**: 12rpx
## 数据流
```
页面加载
调用 fetchDoctors()
获取医生列表
处理数据(添加 isExpert 标记)
渲染医生卡片
```
## API 集成
### 获取医生列表
```javascript
const response = await proxy.apiUrl({
url: '/api/doctor/lists',
method: 'GET',
data: {
page_no: 1,
page_size: 10
}
})
```
### 响应数据处理
```javascript
doctors.value = doctorList.map((doctor, index) => ({
...doctor,
isExpert: index < 2,
reviewCount: Math.floor(Math.random() * 500) + 100
}))
```
## 点击事件
### 医生卡片点击
```javascript
selectDoctor(doctor) {
uni.navigateTo({
url: `/pages/order/index?doctorId=${doctor.id}&doctorName=${doctor.name}`
})
}
```
## 性能优化
- 使用 CSS 动画而非 JS 动画
- 图片使用 `mode="aspectFill"`
- 减少重排和重绘
- 支持图片懒加载
## 无障碍设计
- 足够的色彩对比度
- 清晰的文字标签
- 合理的点击区域 (最小 44x44rpx)
- 支持屏幕阅读器
## 总结
这个设计方案特点:
- ✅ 绿色系中医风格
- ✅ 卡片式布局,清晰明了
- ✅ 完整的医生信息展示
- ✅ 医生资质认证显示
- ✅ 流畅的交互体验
- ✅ 专业的医疗感
整个页面简洁专业,重点突出,用户可以快速了解医生信息并进行咨询。
@@ -1,8 +1,8 @@
import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min.js'; import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min.js';
let SDKAPPID = 1600127710; let SDKAPPID = 1600131325;
let SECRETKEY = '8a6b3ce533b0e46b9d6e17d5c77bac240bc0ccdce4e3db93a0d6a1e55160c73d'; let SECRETKEY = 'adc84842a817f6b9d124a1a15a6de4d0b3a940bef678820ed46d40db474c8ea4';
/** /**
* Expiration time for the signature, it is recommended not to set it too short. * Expiration time for the signature, it is recommended not to set it too short.
-249
View File
@@ -1,249 +0,0 @@
# 中医医院小程序首页 UI 设计指南
## 设计理念
### 核心特点
1. **中医文化融合** - 采用中医传统色彩(棕色、金色)
2. **专业医疗感** - 简洁现代的布局,突出医疗专业性
3. **用户友好** - 清晰的信息层级,便捷的操作流程
4. **视觉层次** - 通过色彩、大小、间距创建清晰的视觉层次
## 色彩方案
### 主色系
- **主色**: `#8B6914` (棕色) - 代表中医传统、稳重、专业
- **辅助色**: `#A0826D` (浅棕) - 用于渐变和背景
- **强调色**: `#FFB800` (金色) - 用于星级评分、重要信息
- **警告色**: `#FF6B6B` (红色) - 用于通知、提醒
### 中性色
- **背景**: `#f8f8f8` - 整体背景
- **卡片**: `#fff` - 内容卡片
- **文字**: `#333` - 主文字
- **辅助**: `#999` - 辅助文字
## 页面结构
### 1. 顶部导航栏 (Header)
```
┌─────────────────────────────────┐
│ 中医医院 🔔 (3) │
└─────────────────────────────────┘
```
- 固定顶部,背景为棕色渐变
- 左侧显示医院名称
- 右侧显示通知图标和未读数
### 2. 搜索栏 (Search Bar)
```
┌─────────────────────────────────┐
│ 🔍 搜索医生或科室 │
└─────────────────────────────────┘
```
- 圆角搜索框,背景为浅灰色
- 支持搜索医生和科室
### 3. 快速导航 (Quick Navigation)
```
┌──────┬──────┬──────┬──────┐
│ 📋 │ 💬 │ 📄 │ ❤️ │
│ 挂号 │ 咨询 │ 记录 │ 档案 │
└──────┴──────┴──────┴──────┘
```
- 4 个快速入口
- 图标 + 文字组合
- 点击跳转到对应页面
### 4. 轮播区域 (Banner)
```
┌─────────────────────────────────┐
│ │
│ [轮播图片] │
│ │
│ 中医药文化 │
│ 传承千年中医精粹,守护您的健康 │
│ [了解更多] │
│ │
└─────────────────────────────────┘
```
- 高度: 300rpx
- 自动轮播,5秒切换
- 底部显示标题、描述和按钮
- 使用渐变遮罩
### 5. 科室推荐 (Departments)
```
┌─────────────────────────────────┐
│ 科室推荐 查看全部 > │
├─────────────────────────────────┤
│ 🫀 👩 👶 │
│ 内科 妇科 儿科 │
│ 中医内科 中医妇科 中医儿科 │
│ │
│ 🦴 🧴 💉 │
│ 骨科 皮肤科 针灸科 │
│ 中医骨科 中医皮肤 针灸推拿 │
└─────────────────────────────────┘
```
- 3 列网格布局
- 6 个科室卡片
- 卡片背景为浅米色
- 点击进入科室详情
### 6. 医生推荐 (Doctors)
```
┌─────────────────────────────────┐
│ 名医推荐 查看全部 > │
├─────────────────────────────────┤
│ ┌─────────────────────────────┐ │
│ │ [头像] 张医生 [咨询] │ │
│ │ 专家 主任医师 │ │
│ │ 中医内科 │ │
│ │ ★★★★★ 4.9 (256) │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ [头像] 李医生 [咨询] │ │
│ │ 副主任医师 │ │
│ │ 中医妇科 │ │
│ │ ★★★★★ 4.8 (189) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────┘
```
- 列表布局,每行一个医生
- 左侧: 头像 + 专家标签
- 中间: 医生信息(名字、职位、科室、评分)
- 右侧: 咨询按钮
- 点击进入医生详情
### 7. 健康资讯 (News)
```
┌─────────────────────────────────┐
│ 健康资讯 更多 > │
├─────────────────────────────────┤
│ [图] 春季养生:如何调理脾胃 │
│ 中医养生 2小时前 │
│ │
│ [图] 中医药在预防疾病中的作用 │
│ 医学资讯 4小时前 │
│ │
│ [图] 穴位按摩缓解颈椎疲劳 │
│ 健康指南 6小时前 │
└─────────────────────────────────┘
```
- 列表布局
- 左侧: 新闻图片
- 右侧: 标题、来源、时间
- 标题最多显示 2 行
## 交互设计
### 按钮状态
- **正常**: 棕色背景,白色文字
- **按下**: 背景变深,有缩放动画
- **禁用**: 灰色背景,不可点击
### 卡片交互
- **正常**: 浅色背景,细边框
- **按下**: 背景变深,有阴影效果
- **悬停**: 轻微缩放
### 动画效果
- **轮播**: 500ms 切换动画
- **卡片**: 300ms 过渡效果
- **按钮**: 100ms 按下效果
## 响应式设计
### 断点
- **小屏幕** (< 375px): 调整间距和字体
- **中屏幕** (375-414px): 标准设计
- **大屏幕** (> 414px): 增加间距
### 适配方案
- 使用 rpx 单位(响应式像素)
- 1rpx = 0.5px (在 375px 宽度下)
- 自动适配不同屏幕尺寸
## 字体规范
### 字体大小
- **标题**: 32rpx (主标题), 28rpx (副标题)
- **正文**: 24rpx (主要内容), 22rpx (次要内容)
- **辅助**: 20rpx (提示信息), 18rpx (标签)
### 字体权重
- **加粗**: 500-700 (标题、重要信息)
- **正常**: 400 (正文)
- **轻细**: 300 (辅助信息)
## 间距规范
### 外间距 (Margin)
- **大**: 30rpx (主要分区)
- **中**: 20rpx (卡片间距)
- **小**: 10rpx (元素间距)
### 内间距 (Padding)
- **大**: 30rpx (卡片内部)
- **中**: 20rpx (按钮、输入框)
- **小**: 10rpx (文字间距)
## 圆角规范
- **大**: 12rpx (卡片、按钮)
- **中**: 8rpx (小卡片、图片)
- **小**: 4rpx (标签、徽章)
- **圆形**: 50% (头像、通知徽章)
## 阴影规范
- **轻**: `0 2rpx 8rpx rgba(0, 0, 0, 0.08)`
- **中**: `0 4rpx 12rpx rgba(0, 0, 0, 0.12)`
- **重**: `0 8rpx 24rpx rgba(0, 0, 0, 0.15)`
## 图片规范
### 尺寸
- **轮播图**: 750x300px
- **医生头像**: 100x100rpx
- **新闻图片**: 140x100rpx
- **科室图标**: 48rpx (emoji)
### 处理
- 使用 `mode="aspectFill"` 保持宽高比
- 圆角处理: 8-12rpx
- 加载占位符: 灰色背景
## 无障碍设计
- 足够的色彩对比度
- 清晰的文字标签
- 合理的点击区域 (最小 44x44rpx)
- 支持屏幕阅读器
## 性能优化
- 图片懒加载
- 列表虚拟滚动
- 减少重排和重绘
- 使用 CSS 动画而非 JS 动画
## 扩展建议
### 可以添加的功能
1. **个性化推荐** - 根据用户历史推荐医生
2. **预约提醒** - 显示即将到来的预约
3. **健康数据** - 显示用户的健康指标
4. **在线客服** - 右下角浮窗
5. **活动促销** - 轮播中添加促销信息
### 可以优化的方面
1. **深色模式** - 支持系统深色模式
2. **多语言** - 支持多种语言
3. **主题切换** - 允许用户自定义主题色
4. **动画增强** - 添加更多微交互
5. **数据统计** - 追踪用户行为
## 总结
这个设计方案结合了中医文化特色和现代医疗应用的需求,通过合理的色彩、布局和交互设计,为用户提供专业、友好的医疗服务体验。
+1 -1
View File
@@ -1,5 +1,5 @@
import App from './App' import App from './App'
var baseUrl ='https://admin.zhenyangtang.com.cn/'; var baseUrl ='https://www.d.com/';
// #ifndef VUE3 // #ifndef VUE3
import Vue from 'vue' import Vue from 'vue'
import './uni.promisify.adaptor' import './uni.promisify.adaptor'
+6
View File
@@ -61,6 +61,12 @@
"style": { "style": {
"navigationBarTitleText": "服务" "navigationBarTitleText": "服务"
} }
},
{
"path": "pages/order/order",
"style": {
"navigationBarTitleText": "付款"
}
} }
], ],
"subPackages": [ "subPackages": [
+272 -60
View File
@@ -59,12 +59,65 @@
<text class="label">糖尿病期数</text> <text class="label">糖尿病期数</text>
<text class="value">{{ getDiabetesTypeName() || '-' }}</text> <text class="value">{{ getDiabetesTypeName() || '-' }}</text>
</view> </view>
<view class="info-item">
<text class="label">婚姻状态</text>
<text class="value">{{ getMaritalStatusName() || '-' }}</text>
</view>
<view class="info-item">
<text class="label">身高</text>
<text class="value">{{ formData.height ? formData.height + ' cm' : '-' }}</text>
</view>
<view class="info-item">
<text class="label">体重</text>
<text class="value">{{ formData.weight ? formData.weight + ' kg' : '-' }}</text>
</view>
<view class="info-item">
<text class="label">地区</text>
<text class="value">{{ formData.region || '-' }}</text>
</view>
<view class="info-item">
<text class="label">收缩压</text>
<text class="value">{{ formData.systolic_pressure ? formData.systolic_pressure + ' mmHg' : '-' }}</text>
</view>
<view class="info-item">
<text class="label">舒张压</text>
<text class="value">{{ formData.diastolic_pressure ? formData.diastolic_pressure + ' mmHg' : '-' }}</text>
</view>
<view class="info-item">
<text class="label">空腹血糖</text>
<text class="value">{{ formData.fasting_blood_sugar ? formData.fasting_blood_sugar + ' mmol/L' : '-' }}</text>
</view>
</view> </view>
<!-- 现病史 --> <!-- 现病史 -->
<view class="section"> <view class="section">
<view class="section-title">现病史</view> <view class="section-title">现病史</view>
<view class="info-item">
<text class="label">患病年数</text>
<text class="value">{{ formData.diabetes_discovery_year ? formData.diabetes_discovery_year + ' 年' : '-' }}</text>
</view>
<view class="info-item">
<text class="label">当地诊断结果</text>
<view class="tag-list">
<text v-for="item in (formData.local_hospital_diagnosis || [])" :key="item" class="tag">{{ item }}</text>
<text v-if="!formData.local_hospital_diagnosis || formData.local_hospital_diagnosis.length === 0" class="value">-</text>
</view>
</view>
<view class="info-item">
<text class="label">当地就诊医院</text>
<text class="value">{{ formData.local_hospital_name || '-' }}</text>
</view>
<view class="info-item"> <view class="info-item">
<text class="label">口腔感觉</text> <text class="label">口腔感觉</text>
<text class="value">{{ getAppetiteName() || '-' }}</text> <text class="value">{{ getAppetiteName() || '-' }}</text>
@@ -108,6 +161,62 @@
<text v-if="getSleepConditionNames().length === 0" class="value">-</text> <text v-if="getSleepConditionNames().length === 0" class="value">-</text>
</view> </view>
</view> </view>
<view class="info-item">
<text class="label">眼睛情况</text>
<view class="tag-list">
<text v-for="item in getMultiNames(formData.eye_condition, eyeConditionOptions)" :key="item" class="tag">{{ item }}</text>
<text v-if="getMultiNames(formData.eye_condition, eyeConditionOptions).length === 0" class="value">-</text>
</view>
</view>
<view class="info-item">
<text class="label">头部感觉</text>
<view class="tag-list">
<text v-for="item in getMultiNames(formData.head_feeling, headFeelingOptions)" :key="item" class="tag">{{ item }}</text>
<text v-if="getMultiNames(formData.head_feeling, headFeelingOptions).length === 0" class="value">-</text>
</view>
</view>
<view class="info-item">
<text class="label">出汗情况</text>
<view class="tag-list">
<text v-for="item in getMultiNames(formData.sweat_condition, sweatConditionOptions)" :key="item" class="tag">{{ item }}</text>
<text v-if="getMultiNames(formData.sweat_condition, sweatConditionOptions).length === 0" class="value">-</text>
</view>
</view>
<view class="info-item">
<text class="label">皮肤情况</text>
<view class="tag-list">
<text v-for="item in getMultiNames(formData.skin_condition, skinConditionOptions)" :key="item" class="tag">{{ item }}</text>
<text v-if="getMultiNames(formData.skin_condition, skinConditionOptions).length === 0" class="value">-</text>
</view>
</view>
<view class="info-item">
<text class="label">小便情况</text>
<view class="tag-list">
<text v-for="item in getMultiNames(formData.urine_condition, urineConditionOptions)" :key="item" class="tag">{{ item }}</text>
<text v-if="getMultiNames(formData.urine_condition, urineConditionOptions).length === 0" class="value">-</text>
</view>
</view>
<view class="info-item">
<text class="label">大便情况</text>
<view class="tag-list">
<text v-for="item in getMultiNames(formData.stool_condition, stoolConditionOptions)" :key="item" class="tag">{{ item }}</text>
<text v-if="getMultiNames(formData.stool_condition, stoolConditionOptions).length === 0" class="value">-</text>
</view>
</view>
<view class="info-item">
<text class="label">腰肾情况</text>
<view class="tag-list">
<text v-for="item in getMultiNames(formData.kidney_condition, kidneyConditionOptions)" :key="item" class="tag">{{ item }}</text>
<text v-if="getMultiNames(formData.kidney_condition, kidneyConditionOptions).length === 0" class="value">-</text>
</view>
</view>
</view> </view>
<!-- 既往史 --> <!-- 既往史 -->
@@ -141,6 +250,16 @@
<text class="label">过敏史</text> <text class="label">过敏史</text>
<text class="value">{{ formData.allergy_history === 1 ? '有' : '无' }}</text> <text class="value">{{ formData.allergy_history === 1 ? '有' : '无' }}</text>
</view> </view>
<view class="info-item">
<text class="label">家族病史</text>
<text class="value">{{ formData.family_history === 1 ? '有' : '无' }}</text>
</view>
<view class="info-item">
<text class="label">妊娠哺乳史</text>
<text class="value">{{ formData.pregnancy_history === 1 ? '有' : '无' }}</text>
</view>
</view> </view>
<!-- 诊断信息 --> <!-- 诊断信息 -->
@@ -190,6 +309,25 @@
<text class="label">医嘱</text> <text class="label">医嘱</text>
<text class="value multi-line">{{ formData.doctor_advice || '-' }}</text> <text class="value multi-line">{{ formData.doctor_advice || '-' }}</text>
</view> </view>
<view class="info-item" v-if="formData.report_files && formData.report_files.length > 0">
<text class="label">检查报告</text>
<view class="image-list">
<image
v-for="(img, index) in formData.report_files"
:key="index"
:src="img"
class="tongue-image"
mode="aspectFill"
@click="previewImage(img)"
/>
</view>
</view>
<view class="info-item">
<text class="label">备注</text>
<text class="value multi-line">{{ formData.remark || '-' }}</text>
</view>
</view> </view>
</view> </view>
@@ -230,24 +368,45 @@ const formData = ref({
diagnosis_type: '', diagnosis_type: '',
syndrome_type: '', syndrome_type: '',
diabetes_type: '', diabetes_type: '',
marital_status: '',
height: '',
weight: '',
region: '',
systolic_pressure: '',
diastolic_pressure: '',
fasting_blood_sugar: '',
diabetes_discovery_year: '',
local_hospital_diagnosis: [],
local_hospital_name: '',
appetite: '', appetite: '',
water_intake: '', water_intake: '',
diet_condition: [], diet_condition: [],
weight_change: '', weight_change: '',
body_feeling: [], body_feeling: [],
sleep_condition: [], sleep_condition: [],
eye_condition: [],
head_feeling: [],
sweat_condition: [],
skin_condition: [],
urine_condition: [],
stool_condition: [],
kidney_condition: [],
fatty_liver_degree: '', fatty_liver_degree: '',
past_history: [], past_history: [],
trauma_history: 0, trauma_history: 0,
surgery_history: 0, surgery_history: 0,
allergy_history: 0, allergy_history: 0,
family_history: 0,
pregnancy_history: 0,
tongue_images: [], tongue_images: [],
report_files: [],
symptoms: '', symptoms: '',
tongue_coating: '', tongue_coating: '',
pulse: '', pulse: '',
treatment_principle: '', treatment_principle: '',
prescription: '', prescription: '',
doctor_advice: '' doctor_advice: '',
remark: ''
}); });
let dingdan_ok=ref(false) let dingdan_ok=ref(false)
// 字典选项 // 字典选项
@@ -262,6 +421,13 @@ const weightChangeOptions = ref([]);
const bodyFeelingOptions = ref([]); const bodyFeelingOptions = ref([]);
const sleepConditionOptions = ref([]); const sleepConditionOptions = ref([]);
const fattyLiverDegreeOptions = ref([]); const fattyLiverDegreeOptions = ref([]);
const eyeConditionOptions = ref([]);
const headFeelingOptions = ref([]);
const sweatConditionOptions = ref([]);
const skinConditionOptions = ref([]);
const urineConditionOptions = ref([]);
const stoolConditionOptions = ref([]);
const kidneyConditionOptions = ref([]);
onMounted(() => { onMounted(() => {
getDictOptions(); getDictOptions();
@@ -282,7 +448,14 @@ const getDictOptions = async () => {
weightChange, weightChange,
bodyFeeling, bodyFeeling,
sleepCondition, sleepCondition,
fattyLiverDegree fattyLiverDegree,
eyeCondition,
headFeeling,
sweatCondition,
skinCondition,
urineCondition,
stoolCondition,
kidneyCondition
] = await Promise.all([ ] = await Promise.all([
getDictData('diagnosis_type'), getDictData('diagnosis_type'),
getDictData('syndrome_type'), getDictData('syndrome_type'),
@@ -294,7 +467,14 @@ const getDictOptions = async () => {
getDictData('weight_change'), getDictData('weight_change'),
getDictData('body_feeling'), getDictData('body_feeling'),
getDictData('sleep_condition'), getDictData('sleep_condition'),
getDictData('fatty_liver_degree') getDictData('fatty_liver_degree'),
getDictData('eye_condition'),
getDictData('head_feeling'),
getDictData('sweat_condition'),
getDictData('skin_condition'),
getDictData('urine_condition'),
getDictData('stool_condition'),
getDictData('kidney_condition')
]); ]);
diagnosisTypeOptions.value = diagnosisType?.diagnosis_type || []; diagnosisTypeOptions.value = diagnosisType?.diagnosis_type || [];
@@ -308,6 +488,13 @@ const getDictOptions = async () => {
bodyFeelingOptions.value = bodyFeeling?.body_feeling || []; bodyFeelingOptions.value = bodyFeeling?.body_feeling || [];
sleepConditionOptions.value = sleepCondition?.sleep_condition || []; sleepConditionOptions.value = sleepCondition?.sleep_condition || [];
fattyLiverDegreeOptions.value = fattyLiverDegree?.fatty_liver_degree || []; fattyLiverDegreeOptions.value = fattyLiverDegree?.fatty_liver_degree || [];
eyeConditionOptions.value = eyeCondition?.eye_condition || [];
headFeelingOptions.value = headFeeling?.head_feeling || [];
sweatConditionOptions.value = sweatCondition?.sweat_condition || [];
skinConditionOptions.value = skinCondition?.skin_condition || [];
urineConditionOptions.value = urineCondition?.urine_condition || [];
stoolConditionOptions.value = stoolCondition?.stool_condition || [];
kidneyConditionOptions.value = kidneyCondition?.kidney_condition || [];
} catch (error) { } catch (error) {
console.error('获取字典数据失败:', error); console.error('获取字典数据失败:', error);
} }
@@ -487,17 +674,31 @@ const getSleepConditionNames = () => {
const getPastHistoryNames = () => { const getPastHistoryNames = () => {
if (!formData.value.past_history || formData.value.past_history.length === 0) return []; if (!formData.value.past_history || formData.value.past_history.length === 0) return [];
// 处理字符串类型(逗号分隔)或数组类型
const values = Array.isArray(formData.value.past_history) const values = Array.isArray(formData.value.past_history)
? formData.value.past_history ? formData.value.past_history
: formData.value.past_history.split(','); : formData.value.past_history.split(',');
return values.map(val => { return values.map(val => {
const item = pastHistoryOptions.value.find(i => i.value === val); const item = pastHistoryOptions.value.find(i => i.value === val);
return item ? item.name : val; return item ? item.name : val;
}).filter(Boolean); }).filter(Boolean);
}; };
// 通用多选名称获取
const getMultiNames = (fieldValues, options) => {
if (!fieldValues || fieldValues.length === 0) return [];
const values = Array.isArray(fieldValues) ? fieldValues : fieldValues.split(',');
return values.map(val => {
const item = options.find(i => i.value === val);
return item ? item.name : val;
}).filter(Boolean);
};
const getMaritalStatusName = () => {
const map = { 0: '未婚', 1: '已婚', 2: '离异' };
const v = formData.value.marital_status;
return (v !== '' && v !== undefined && v !== null) ? (map[v] || '-') : '';
};
// 预览图片 // 预览图片
const previewImage = (current) => { const previewImage = (current) => {
uni.previewImage({ uni.previewImage({
@@ -553,6 +754,7 @@ const confirmDiagnosis = async () => {
icon: 'none', icon: 'none',
duration: 2000 duration: 2000
}); });
dingdan_ok.value=res.data.is_view?true:false
uni.setStorageSync('dingdan_ok', true); uni.setStorageSync('dingdan_ok', true);
dingdan_ok.value=true; dingdan_ok.value=true;
setTimeout(() => { setTimeout(() => {
@@ -573,34 +775,37 @@ const confirmDiagnosis = async () => {
<style lang="scss"> <style lang="scss">
.container { .container {
min-height: 100vh; min-height: 100vh;
background-color: #f5f5f5; background-color: #f0f0f0;
} }
.form-wrapper { .form-wrapper {
padding: 20rpx; padding: 24rpx;
padding-bottom: 140rpx; /* 为底部按钮留出空间 */ padding-bottom: 180rpx; /* 为底部按钮留出空间 */
} }
.section { .section {
background-color: #fff; background-color: #fff;
border-radius: 16rpx; border-radius: 20rpx;
padding: 30rpx; padding: 40rpx;
margin-bottom: 20rpx; margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
} }
.section-title { .section-title {
font-size: 32rpx; font-size: 40rpx; /* 大字体,老年人易读 */
font-weight: bold; font-weight: bold;
color: #333; color: #1a1a1a;
margin-bottom: 30rpx; margin-bottom: 36rpx;
padding-bottom: 20rpx; padding-bottom: 24rpx;
border-bottom: 2rpx solid #f0f0f0; border-bottom: 3rpx solid #e0e0e0;
letter-spacing: 2rpx;
} }
.info-item { .info-item {
display: flex; display: flex;
margin-bottom: 24rpx; align-items: flex-start;
line-height: 1.6; margin-bottom: 36rpx; /* 加大行间距,减少视觉拥挤 */
line-height: 1.8;
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
@@ -609,21 +814,23 @@ const confirmDiagnosis = async () => {
.label { .label {
flex-shrink: 0; flex-shrink: 0;
width: 180rpx; width: 200rpx;
font-size: 28rpx; font-size: 34rpx; /* 放大标签字体 */
color: #666; color: #555;
font-weight: 500; font-weight: 600;
padding-top: 2rpx;
} }
.value { .value {
flex: 1; flex: 1;
font-size: 28rpx; font-size: 34rpx; /* 放大内容字体 */
color: #333; color: #111; /* 深色,高对比度 */
word-break: break-all; word-break: break-all;
line-height: 1.8;
&.multi-line { &.multi-line {
white-space: pre-wrap; white-space: pre-wrap;
line-height: 1.8; line-height: 2.0;
} }
} }
@@ -631,29 +838,32 @@ const confirmDiagnosis = async () => {
flex: 1; flex: 1;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 16rpx; gap: 20rpx;
} }
.tag { .tag {
display: inline-block; display: inline-block;
padding: 8rpx 20rpx; padding: 12rpx 28rpx; /* 更大的点击区域 */
background-color: #f0f5ff; background-color: #e8f4ff;
color: #1890ff; color: #0066cc; /* 深蓝,对比度更高 */
font-size: 24rpx; font-size: 32rpx; /* 标签字体也放大 */
border-radius: 8rpx; font-weight: 500;
border-radius: 10rpx;
border: 1rpx solid #b3d9ff;
} }
.image-list { .image-list {
flex: 1; flex: 1;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 20rpx; gap: 24rpx;
} }
.tongue-image { .tongue-image {
width: 200rpx; width: 220rpx;
height: 200rpx; height: 220rpx;
border-radius: 8rpx; border-radius: 12rpx;
border: 2rpx solid #e0e0e0;
} }
.fixed-bottom { .fixed-bottom {
@@ -661,22 +871,23 @@ const confirmDiagnosis = async () => {
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
padding: 20rpx 30rpx; padding: 24rpx 40rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
background: linear-gradient(to top, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0.95) 80%, rgba(255, 255, 255, 0) 100%); background: linear-gradient(to top, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0.95) 80%, rgba(255, 255, 255, 0) 100%);
z-index: 100; z-index: 100;
} }
.confirm-btn { .confirm-btn {
width: 100%; width: 100%;
height: 88rpx; height: 110rpx; /* 更高的按钮,老年人更容易点击 */
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); background: linear-gradient(135deg, #2e7d32 0%, #43a047 100%); /* 绿色,更直观 */
color: #fff; color: #fff;
font-size: 32rpx; font-size: 40rpx; /* 按钮字体放大 */
font-weight: 500; font-weight: bold;
border-radius: 44rpx; border-radius: 55rpx;
border: none; border: none;
box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.3); box-shadow: 0 8rpx 24rpx rgba(46, 125, 50, 0.35);
letter-spacing: 4rpx;
} }
/* 确认成功页面样式 */ /* 确认成功页面样式 */
@@ -685,16 +896,16 @@ const confirmDiagnosis = async () => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); background: linear-gradient(135deg, #2e7d32 0%, #43a047 100%);
padding: 40rpx; padding: 40rpx;
} }
.success-content { .success-content {
width: 100%; width: 100%;
max-width: 600rpx; max-width: 620rpx;
background: #fff; background: #fff;
border-radius: 32rpx; border-radius: 32rpx;
padding: 80rpx 40rpx 60rpx; padding: 90rpx 50rpx 70rpx;
text-align: center; text-align: center;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15); box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
animation: successFadeIn 0.5s ease-out; animation: successFadeIn 0.5s ease-out;
@@ -712,19 +923,19 @@ const confirmDiagnosis = async () => {
} }
.success-icon-wrapper { .success-icon-wrapper {
margin-bottom: 40rpx; margin-bottom: 48rpx;
} }
.success-icon-circle { .success-icon-circle {
width: 160rpx; width: 180rpx;
height: 160rpx; height: 180rpx;
margin: 0 auto; margin: 0 auto;
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%); background: linear-gradient(135deg, #2e7d32 0%, #66bb6a 100%);
border-radius: 50%; border-radius: 50%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow: 0 12rpx 40rpx rgba(82, 196, 26, 0.3); box-shadow: 0 12rpx 40rpx rgba(46, 125, 50, 0.35);
animation: successScale 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275); animation: successScale 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
} }
@@ -743,18 +954,19 @@ const confirmDiagnosis = async () => {
} }
.success-icon-check { .success-icon-check {
font-size: 100rpx; font-size: 110rpx;
color: #fff; color: #fff;
font-weight: bold; font-weight: bold;
line-height: 1; line-height: 1;
} }
.success-title { .success-title {
font-size: 48rpx; font-size: 56rpx; /* 成功标题大字 */
font-weight: bold; font-weight: bold;
color: #333; color: #1a1a1a;
margin-bottom: 24rpx; margin-bottom: 28rpx;
animation: successSlideIn 0.6s ease-out 0.2s both; animation: successSlideIn 0.6s ease-out 0.2s both;
letter-spacing: 4rpx;
} }
@keyframes successSlideIn { @keyframes successSlideIn {
@@ -769,16 +981,16 @@ const confirmDiagnosis = async () => {
} }
.success-message { .success-message {
font-size: 28rpx; font-size: 36rpx; /* 提示文字也放大 */
color: #666; color: #444;
line-height: 1.6; line-height: 1.8;
margin-bottom: 16rpx; margin-bottom: 16rpx;
animation: successSlideIn 0.6s ease-out 0.3s both; animation: successSlideIn 0.6s ease-out 0.3s both;
} }
.success-tips { .success-tips {
font-size: 24rpx; font-size: 30rpx;
color: #999; color: #777;
animation: successSlideIn 0.6s ease-out 0.4s both; animation: successSlideIn 0.6s ease-out 0.4s both;
} }
</style> </style>
+535
View File
@@ -0,0 +1,535 @@
<template>
<view class="container">
<!-- 加载中 -->
<view v-if="loading" class="loading-wrapper">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<!-- 支付成功 -->
<view v-else-if="paySuccess" class="success-container">
<view class="success-content">
<view class="success-icon-wrapper">
<view class="success-icon-circle">
<text class="success-icon-check"></text>
</view>
</view>
<view class="success-title">支付成功</view>
<view class="success-amount">¥ {{ orderInfo.amount }}</view>
<view class="success-message">订单号{{ orderInfo.order_no }}</view>
</view>
</view>
<!-- 订单不存在 / 错误 -->
<view v-else-if="errorMsg" class="error-wrapper">
<view class="error-icon">!</view>
<text class="error-text">{{ errorMsg }}</text>
<button class="retry-btn" @click="loadOrderDetail">重试</button>
</view>
<!-- 订单详情 & 付款 -->
<view v-else-if="orderInfo" class="pay-wrapper">
<!-- 商户信息 -->
<view class="merchant-info">
<text class="merchant-title">付款给甄养堂医院</text>
</view>
<!-- 金额区域 -->
<view class="amount-section">
<text class="amount-label">付款金额</text>
<view class="amount-row">
<text class="amount-symbol">¥</text>
<text class="amount-value">{{ formatAmount(orderInfo.amount) }}</text>
</view>
</view>
<view class="divider"></view>
<!-- 订单信息 -->
<view class="order-info-section">
<view class="info-row">
<text class="info-label">订单号</text>
<text class="info-value">{{ orderInfo.order_no }}</text>
</view>
<view class="info-row">
<text class="info-label">订单类型</text>
<text class="info-value">{{ orderInfo.order_type_desc }}</text>
</view>
<view class="info-row" v-if="orderInfo.remark">
<text class="info-label">备注</text>
<text class="info-value">{{ orderInfo.remark }}</text>
</view>
</view>
<view class="divider"></view>
<!-- 订单状态 -->
<view v-if="orderInfo.status == 2" class="paid-notice">
<view class="paid-icon"></view>
<text class="paid-text">该订单已支付</text>
</view>
<!-- 付款按钮 -->
<view v-else class="pay-btn-wrapper">
<button
class="pay-btn"
:disabled="paying"
:loading="paying"
@click="handlePay"
>
{{ paying ? '支付中...' : '付款' }}
</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const loading = ref(true)
const paying = ref(false)
const paySuccess = ref(false)
const errorMsg = ref('')
const orderInfo = ref(null)
const orderNo = ref('')
onMounted(() => {
loadOrderDetail()
})
const parsePageParams = (options) => {
const params = {}
if (options.scene) {
try {
const decodedScene = decodeURIComponent(options.scene)
decodedScene.split('&').forEach(item => {
const [key, value] = item.split('=')
if (key && value) {
params[key] = value
}
})
} catch (error) {
console.error('解析scene参数失败:', error)
}
}
Object.keys(options).forEach(key => {
if (key !== 'scene' && options[key]) {
params[key] = options[key]
}
})
return params
}
const loadOrderDetail = async () => {
loading.value = true
errorMsg.value = ''
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const params = parsePageParams(currentPage.options || {})
orderNo.value = params.order_no || ''
if (!orderNo.value) {
loading.value = false
errorMsg.value = '缺少订单号'
return
}
try {
const res = await proxy.apiUrl({
url: '/api/tcm/getOrderByNo',
method: 'GET',
data: { order_no: orderNo.value }
}, false)
if (res.code === 1) {
orderInfo.value = res.data
} else {
errorMsg.value = res.msg || '订单加载失败'
}
} catch (err) {
errorMsg.value = '网络请求失败'
console.error('加载订单失败:', err)
} finally {
loading.value = false
}
}
const formatAmount = (amount) => {
const num = parseFloat(amount)
if (isNaN(num)) return '0.00'
return num.toFixed(2)
}
const ensureLogin = () => {
return new Promise((resolve, reject) => {
const token = uni.getStorageSync('token')
if (token) {
resolve(token)
return
}
uni.login({
provider: 'weixin',
success: async (loginRes) => {
try {
const res = await proxy.apiUrl({
url: '/api/login/mnpLogin',
method: 'POST',
data: { code: loginRes.code }
}, false)
if (res.code === 1 && res.data && res.data.token) {
uni.setStorageSync('token', res.data.token)
uni.setStorageSync('userData', res.data)
resolve(res.data.token)
} else {
reject(new Error(res.msg || '登录失败'))
}
} catch (e) {
reject(e)
}
},
fail: (err) => {
reject(err)
}
})
})
}
const handlePay = async () => {
if (paying.value || !orderInfo.value) return
if (orderInfo.value.status == 2) {
uni.showToast({ title: '订单已支付', icon: 'none' })
return
}
paying.value = true
try {
await ensureLogin()
const res = await proxy.apiUrl({
url: '/api/pay/prepay',
method: 'POST',
data: {
from: 'order',
order_id: orderInfo.value.id,
pay_way: 2,
redirect: '/pages/order/order'
}
}, false)
if (res.code !== 1 || !res.data) {
uni.showToast({ title: res.msg || '发起支付失败', icon: 'none' })
paying.value = false
return
}
const payParams = res.data
wx.requestPayment({
timeStamp: payParams.timeStamp,
nonceStr: payParams.nonceStr,
package: payParams.package,
signType: payParams.signType || 'RSA',
paySign: payParams.paySign,
success: () => {
paySuccess.value = true
paying.value = false
},
fail: (err) => {
paying.value = false
if (err.errMsg && err.errMsg.includes('cancel')) {
uni.showToast({ title: '已取消支付', icon: 'none' })
} else {
uni.showToast({ title: '支付失败,请重试', icon: 'none' })
}
console.error('支付失败:', err)
}
})
} catch (err) {
paying.value = false
uni.showToast({ title: '支付异常,请重试', icon: 'none' })
console.error('支付异常:', err)
}
}
</script>
<style lang="less">
.container {
min-height: 100vh;
background-color: #f5f5f5;
}
.loading-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 6rpx solid #e0e0e0;
border-top-color: #1989fa;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.loading-text {
margin-top: 20rpx;
font-size: 28rpx;
color: #999;
}
/* 错误页 */
.error-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
padding: 40rpx;
}
.error-icon {
width: 120rpx;
height: 120rpx;
line-height: 120rpx;
text-align: center;
font-size: 70rpx;
font-weight: bold;
color: #fff;
background-color: #ff4d4f;
border-radius: 50%;
margin-bottom: 30rpx;
}
.error-text {
font-size: 32rpx;
color: #666;
margin-bottom: 40rpx;
}
.retry-btn {
width: 320rpx;
height: 88rpx;
line-height: 88rpx;
text-align: center;
background-color: #1989fa;
color: #fff;
font-size: 32rpx;
border-radius: 44rpx;
border: none;
}
/* 付款主体 */
.pay-wrapper {
padding: 40rpx;
}
.merchant-info {
padding: 30rpx 0;
}
.merchant-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
/* 金额区域 */
.amount-section {
padding: 40rpx 0 50rpx;
}
.amount-label {
font-size: 28rpx;
color: #888;
margin-bottom: 16rpx;
display: block;
}
.amount-row {
display: flex;
align-items: baseline;
margin-top: 16rpx;
}
.amount-symbol {
font-size: 44rpx;
font-weight: bold;
color: #333;
margin-right: 8rpx;
}
.amount-value {
font-size: 80rpx;
font-weight: bold;
color: #333;
line-height: 1;
}
.divider {
height: 1rpx;
background-color: #e8e8e8;
margin: 10rpx 0 30rpx;
}
/* 订单信息 */
.order-info-section {
padding: 10rpx 0 20rpx;
}
.info-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 24rpx;
}
.info-label {
font-size: 28rpx;
color: #888;
flex-shrink: 0;
margin-right: 20rpx;
}
.info-value {
font-size: 28rpx;
color: #333;
text-align: right;
word-break: break-all;
}
/* 已支付提示 */
.paid-notice {
display: flex;
align-items: center;
justify-content: center;
padding: 40rpx 0;
}
.paid-icon {
width: 48rpx;
height: 48rpx;
line-height: 48rpx;
text-align: center;
font-size: 28rpx;
color: #fff;
background-color: #52c41a;
border-radius: 50%;
margin-right: 16rpx;
}
.paid-text {
font-size: 32rpx;
color: #52c41a;
font-weight: 600;
}
/* 付款按钮 */
.pay-btn-wrapper {
padding: 60rpx 40rpx 0;
}
.pay-btn {
width: 100%;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #1989fa;
color: #fff;
font-size: 36rpx;
font-weight: bold;
border-radius: 16rpx;
border: none;
letter-spacing: 4rpx;
&[disabled] {
background-color: #a0cfff;
}
}
/* 支付成功页 */
.success-container {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #1989fa 0%, #4da6ff 100%);
padding: 40rpx;
}
.success-content {
width: 100%;
max-width: 620rpx;
background: #fff;
border-radius: 32rpx;
padding: 90rpx 50rpx 70rpx;
text-align: center;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
animation: fadeIn 0.5s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-40rpx); }
to { opacity: 1; transform: translateY(0); }
}
.success-icon-wrapper {
margin-bottom: 48rpx;
}
.success-icon-circle {
width: 180rpx;
height: 180rpx;
margin: 0 auto;
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 12rpx 40rpx rgba(82, 196, 26, 0.35);
animation: scaleIn 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes scaleIn {
0% { transform: scale(0); opacity: 0; }
50% { transform: scale(1.1); }
100% { transform: scale(1); opacity: 1; }
}
.success-icon-check {
font-size: 110rpx;
color: #fff;
font-weight: bold;
line-height: 1;
}
.success-title {
font-size: 52rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.success-amount {
font-size: 56rpx;
font-weight: bold;
color: #1989fa;
margin-bottom: 30rpx;
}
.success-message {
font-size: 28rpx;
color: #999;
}
</style>
+46
View File
@@ -0,0 +1,46 @@
import request from '@/utils/request'
// 粉丝列表
export function fanLists(params: any) {
return request.get({ url: '/fan/lists', params })
}
// 添加粉丝
export function fanAdd(params: any) {
return request.post({ url: '/fan/add', params })
}
// 编辑粉丝
export function fanEdit(params: any) {
return request.post({ url: '/fan/edit', params })
}
// 删除粉丝
export function fanDelete(params: any) {
return request.post({ url: '/fan/delete', params })
}
// 粉丝详情
export function fanDetail(params: any) {
return request.get({ url: '/fan/detail', params })
}
// 回访记录列表
export function fanVisitRecordLists(params: any) {
return request.get({ url: '/fan/visitRecordLists', params })
}
// 添加回访记录
export function fanVisitRecordAdd(params: any) {
return request.post({ url: '/fan/addVisitRecord', params })
}
// 编辑回访记录
export function fanVisitRecordEdit(params: any) {
return request.post({ url: '/fan/editVisitRecord', params })
}
// 删除回访记录
export function fanVisitRecordDelete(params: any) {
return request.post({ url: '/fan/deleteVisitRecord', params })
}
+32
View File
@@ -105,3 +105,35 @@ export function getCallRecords(params: any) {
export function generateMiniProgramQrcode(params: any) { export function generateMiniProgramQrcode(params: any) {
return request.post({ url: '/tcm.diagnosis/generateMiniProgramQrcode', params }) return request.post({ url: '/tcm.diagnosis/generateMiniProgramQrcode', params })
} }
// 生成订单小程序码
export function generateOrderQrcode(params: any) {
return request.post({ url: '/tcm.diagnosis/generateOrderQrcode', params })
}
// ========== 企业微信聊天记录 ==========
// 获取企业微信聊天记录
export function getWechatChatRecords(params: any) {
return request.get({ url: '/tcm.diagnosis/getWechatChatRecords', params })
}
// 添加企业微信聊天记录
export function addWechatChatRecord(params: any) {
return request.post({ url: '/tcm.diagnosis/addWechatChatRecord', params })
}
// 删除企业微信聊天记录
export function deleteWechatChatRecord(params: any) {
return request.post({ url: '/tcm.diagnosis/deleteWechatChatRecord', params })
}
// 获取企业微信外部联系人信息
export function getWechatExternalContact(params: any) {
return request.get({ url: '/tcm.diagnosis/getWechatExternalContact', params })
}
// 获取会话内容存档开启的成员列表
export function getMsgAuditPermitUsers() {
return request.get({ url: '/tcm.diagnosis/getMsgAuditPermitUsers' })
}
+8
View File
@@ -52,6 +52,14 @@ export const constantRoutes: Array<RouteRecordRaw> = [
{ {
path: '/decoration/pc_details', path: '/decoration/pc_details',
component: () => import('@/views/decoration/pc_details.vue') component: () => import('@/views/decoration/pc_details.vue')
},
{
path: '/fans/h5',
component: () => import('@/views/fans/h5.vue')
},
{
path: '/tcm/diagnosis/h5',
component: () => import('@/views/tcm/diagnosis/index_h5.vue')
} }
// { // {
// path: '/dev_tools', // path: '/dev_tools',
+770
View File
@@ -0,0 +1,770 @@
<template>
<div class="fans-h5">
<!-- 顶部搜索 -->
<div class="h5-header">
<div class="h5-search">
<el-input
v-model="keyword"
placeholder="搜索姓名 / 手机号"
clearable
prefix-icon="Search"
@keyup.enter="handleSearch"
@clear="handleSearch"
/>
</div>
<div class="h5-filter-row">
<el-select v-model="formData.gender" placeholder="性别" clearable size="small" @change="handleSearch">
<el-option label="男" :value="1" />
<el-option label="女" :value="2" />
</el-select>
<el-select v-model="formData.status" placeholder="状态" clearable size="small" @change="handleSearch">
<el-option label="启用" :value="1" />
<el-option label="禁用" :value="0" />
</el-select>
<el-button type="primary" size="small" @click="handleSearch">查询</el-button>
<el-button size="small" @click="handleReset">重置</el-button>
</div>
</div>
<!-- 粉丝卡片列表 -->
<div class="h5-list" v-loading="listLoading">
<div v-if="fanList.length === 0 && !listLoading" class="h5-empty">
<el-empty description="暂无粉丝数据" />
</div>
<div
v-for="item in fanList"
:key="item.id"
class="h5-card"
>
<div class="h5-card-header">
<div class="h5-card-name">
<span class="name">{{ item.name }}</span>
<el-tag size="small" :type="item.gender === 1 ? '' : item.gender === 2 ? 'danger' : 'info'" effect="plain">
{{ item.gender_desc }}
</el-tag>
<span v-if="item.age" class="age">{{ item.age }}</span>
</div>
<el-tag size="small" :type="item.status == 1 ? 'success' : 'danger'">
{{ item.status == 1 ? '启用' : '禁用' }}
</el-tag>
</div>
<div class="h5-card-body">
<div class="info-line">
<span class="label">手机</span>
<span class="value">{{ item.phone || '-' }}</span>
</div>
<div class="info-line">
<span class="label">身份证</span>
<span class="value">{{ item.id_card || '-' }}</span>
</div>
<div v-if="item.remark" class="info-line">
<span class="label">备注</span>
<span class="value remark">{{ item.remark }}</span>
</div>
</div>
<div class="h5-card-footer">
<div class="footer-left">
<div class="visit-info">
回访 <span class="visit-count">{{ item.visit_count || 0 }}</span>
</div>
<div v-if="item.creator_name" class="creator-info">
登记人{{ item.creator_name }}
</div>
</div>
<div class="actions">
<el-button type="primary" text size="small" @click="handleEdit(item)">编辑</el-button>
<el-button type="success" text size="small" @click="handleVisitRecords(item)">回访</el-button>
<el-button type="danger" text size="small" @click="handleDelete(item)">删除</el-button>
</div>
</div>
</div>
<!-- 加载更多 -->
<div v-if="hasMore" class="h5-load-more" @click="loadMore">
<span v-if="!moreLoading">加载更多</span>
<span v-else>加载中...</span>
</div>
<div v-if="!hasMore && fanList.length > 0" class="h5-no-more">没有更多了</div>
</div>
<!-- 悬浮新增按钮 -->
<div class="h5-fab" @click="handleAdd">
<el-icon :size="24"><Plus /></el-icon>
</div>
<!-- 新增/编辑粉丝 -->
<el-drawer
v-model="fanDrawerVisible"
:title="fanDialogType === 'add' ? '新增粉丝' : '编辑粉丝'"
direction="btt"
size="85%"
:close-on-click-modal="false"
@closed="resetFanForm"
>
<el-form
ref="fanFormRef"
:model="fanForm"
:rules="fanRules"
label-position="top"
class="h5-form"
>
<el-form-item label="姓名" prop="name">
<el-input v-model="fanForm.name" placeholder="请输入姓名" maxlength="50" />
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="fanForm.phone" placeholder="请输入手机号" maxlength="11" />
</el-form-item>
<el-form-item label="身份证号" prop="id_card">
<el-input v-model="fanForm.id_card" placeholder="请输入身份证号码" maxlength="18" />
</el-form-item>
<div class="h5-form-row">
<el-form-item label="年龄" prop="age" class="flex-1">
<el-input-number v-model="fanForm.age" :min="0" :max="150" controls-position="right" class="!w-full" />
</el-form-item>
<el-form-item label="性别" prop="gender" class="flex-1">
<el-radio-group v-model="fanForm.gender">
<el-radio :label="1"></el-radio>
<el-radio :label="2"></el-radio>
</el-radio-group>
</el-form-item>
</div>
<el-form-item label="状态">
<el-switch v-model="fanForm.status" :active-value="1" :inactive-value="0" active-text="启用" inactive-text="禁用" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="fanForm.remark" type="textarea" :rows="3" placeholder="请输入备注" maxlength="500" show-word-limit />
</el-form-item>
</el-form>
<template #footer>
<el-button class="flex-1" @click="fanDrawerVisible = false">取消</el-button>
<el-button class="flex-1" type="primary" :loading="fanSubmitLoading" @click="handleFanSubmit">确定</el-button>
</template>
</el-drawer>
<!-- 回访记录 -->
<el-drawer
v-model="visitDrawerVisible"
:title="`回访记录 - ${currentFan?.name || ''}`"
direction="rtl"
size="100%"
:close-on-click-modal="false"
>
<div class="h5-visit-header">
<el-button type="primary" size="small" @click="handleAddVisitRecord">+ 新增回访</el-button>
</div>
<div class="h5-visit-list" v-loading="visitLoading">
<div v-if="visitRecords.length === 0 && !visitLoading" class="h5-empty">
<el-empty description="暂无回访记录" :image-size="80" />
</div>
<div v-for="item in visitRecords" :key="item.id" class="h5-visit-card">
<div class="visit-card-header">
<div class="visit-card-tags">
<el-tag size="small" :type="visitTypeTagMap[item.visit_type]">{{ item.visit_type_desc }}</el-tag>
<span class="visit-time">{{ item.visit_time_text }}</span>
</div>
<div class="visit-card-actions">
<el-button type="primary" text size="small" @click="handleEditVisitRecord(item)">编辑</el-button>
<el-button type="danger" text size="small" @click="handleDeleteVisitRecord(item.id)">删除</el-button>
</div>
</div>
<div class="visit-card-content">{{ item.content }}</div>
<div v-if="item.result" class="visit-card-result">
<span class="label">结果</span>{{ item.result }}
</div>
<div class="visit-card-meta">
<span v-if="item.next_visit_time_text" class="next-visit">下次回访{{ item.next_visit_time_text }}</span>
<span v-if="item.operator_name" class="operator">{{ item.operator_name }}</span>
</div>
</div>
<div v-if="visitTotal > visitRecords.length" class="h5-load-more" @click="loadMoreVisitRecords">
加载更多
</div>
</div>
</el-drawer>
<!-- 新增/编辑回访记录 -->
<el-drawer
v-model="visitFormDrawerVisible"
:title="visitDialogType === 'add' ? '新增回访记录' : '编辑回访记录'"
direction="btt"
size="80%"
:close-on-click-modal="false"
@closed="resetVisitForm"
>
<el-form
ref="visitFormRef"
:model="visitForm"
:rules="visitRules"
label-position="top"
class="h5-form"
>
<el-form-item label="回访类型" prop="visit_type">
<el-radio-group v-model="visitForm.visit_type" class="h5-radio-group">
<el-radio-button :label="1">电话</el-radio-button>
<el-radio-button :label="2">微信</el-radio-button>
<el-radio-button :label="3">短信</el-radio-button>
<el-radio-button :label="4">上门</el-radio-button>
<el-radio-button :label="5">其他</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="回访时间" prop="visit_time">
<el-date-picker
v-model="visitForm.visit_time"
type="datetime"
placeholder="请选择回访时间"
value-format="YYYY-MM-DD HH:mm:ss"
class="!w-full"
/>
</el-form-item>
<el-form-item label="回访内容" prop="content">
<el-input v-model="visitForm.content" type="textarea" :rows="4" placeholder="请输入回访内容" />
</el-form-item>
<el-form-item label="回访结果">
<el-input v-model="visitForm.result" type="textarea" :rows="3" placeholder="请输入回访结果" />
</el-form-item>
<el-form-item label="下次回访时间">
<el-date-picker
v-model="visitForm.next_visit_time"
type="datetime"
placeholder="请选择下次回访时间"
value-format="YYYY-MM-DD HH:mm:ss"
class="!w-full"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button class="flex-1" @click="visitFormDrawerVisible = false">取消</el-button>
<el-button class="flex-1" type="primary" :loading="visitSubmitLoading" @click="handleVisitSubmit">确定</el-button>
</template>
</el-drawer>
</div>
</template>
<script setup lang="ts" name="fansH5">
import {
fanLists,
fanAdd,
fanEdit,
fanDelete,
fanVisitRecordLists,
fanVisitRecordAdd,
fanVisitRecordEdit,
fanVisitRecordDelete
} from '@/api/fans'
import feedback from '@/utils/feedback'
import dayjs from 'dayjs'
import { Plus } from '@element-plus/icons-vue'
import type { FormInstance, FormRules } from 'element-plus'
// ==================== 粉丝列表 ====================
const keyword = ref('')
const formData = ref({
name: '',
phone: '',
gender: '' as string | number,
status: '' as string | number
})
const fanList = ref<any[]>([])
const listLoading = ref(false)
const moreLoading = ref(false)
const pageNo = ref(1)
const pageSize = 15
const total = ref(0)
const hasMore = computed(() => fanList.value.length < total.value)
const loadList = async (isLoadMore = false) => {
if (isLoadMore) {
moreLoading.value = true
} else {
listLoading.value = true
}
try {
const params: any = {
page_no: pageNo.value,
page_size: pageSize,
...formData.value
}
if (keyword.value) {
if (/^\d+$/.test(keyword.value)) {
params.phone = keyword.value
} else {
params.name = keyword.value
}
}
const res = await fanLists(params)
if (isLoadMore) {
fanList.value = [...fanList.value, ...(res.lists || [])]
} else {
fanList.value = res.lists || []
}
total.value = res.count || 0
} catch (error) {
console.error(error)
} finally {
listLoading.value = false
moreLoading.value = false
}
}
const handleSearch = () => {
pageNo.value = 1
loadList()
}
const handleReset = () => {
keyword.value = ''
formData.value = { name: '', phone: '', gender: '', status: '' }
handleSearch()
}
const loadMore = () => {
if (moreLoading.value) return
pageNo.value++
loadList(true)
}
// ==================== 新增/编辑粉丝 ====================
const fanDrawerVisible = ref(false)
const fanDialogType = ref<'add' | 'edit'>('add')
const fanFormRef = ref<FormInstance>()
const fanSubmitLoading = ref(false)
const fanForm = ref({
id: 0, name: '', phone: '', id_card: '', age: 0, gender: 1, status: 1, remark: ''
})
const fanRules: FormRules = {
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
],
id_card: [
{ pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '身份证号格式不正确', trigger: 'blur' }
],
gender: [{ required: true, message: '请选择性别', trigger: 'change' }]
}
const handleAdd = () => {
fanDialogType.value = 'add'
fanDrawerVisible.value = true
}
const handleEdit = (row: any) => {
fanDialogType.value = 'edit'
fanForm.value = {
id: row.id, name: row.name, phone: row.phone, id_card: row.id_card,
age: row.age, gender: row.gender, status: row.status, remark: row.remark
}
fanDrawerVisible.value = true
}
const resetFanForm = () => {
fanForm.value = { id: 0, name: '', phone: '', id_card: '', age: 0, gender: 1, status: 1, remark: '' }
fanFormRef.value?.resetFields()
}
const handleFanSubmit = async () => {
await fanFormRef.value?.validate()
fanSubmitLoading.value = true
try {
if (fanDialogType.value === 'add') {
await fanAdd(fanForm.value)
} else {
await fanEdit(fanForm.value)
}
fanDrawerVisible.value = false
handleSearch()
} catch (error: any) {
} finally {
fanSubmitLoading.value = false
}
}
const handleDelete = async (item: any) => {
await feedback.confirm(`确定删除粉丝「${item.name}」吗?`)
try {
await fanDelete({ id: item.id })
handleSearch()
} catch (error: any) {
}
}
// ==================== 回访记录 ====================
const visitDrawerVisible = ref(false)
const currentFan = ref<any>(null)
const visitRecords = ref<any[]>([])
const visitLoading = ref(false)
const visitTotal = ref(0)
const visitPageNo = ref(1)
const visitTypeTagMap: Record<number, string> = {
1: '', 2: 'success', 3: 'info', 4: 'warning', 5: 'danger'
}
const handleVisitRecords = (row: any) => {
currentFan.value = row
visitDrawerVisible.value = true
visitPageNo.value = 1
visitRecords.value = []
loadVisitRecords()
}
const loadVisitRecords = async () => {
visitLoading.value = true
try {
const res = await fanVisitRecordLists({
fan_id: currentFan.value.id,
page_no: visitPageNo.value,
page_size: 15
})
if (visitPageNo.value === 1) {
visitRecords.value = res.lists || []
} else {
visitRecords.value = [...visitRecords.value, ...(res.lists || [])]
}
visitTotal.value = res.count || 0
} catch (error) {
console.error(error)
} finally {
visitLoading.value = false
}
}
const loadMoreVisitRecords = () => {
visitPageNo.value++
loadVisitRecords()
}
// ==================== 新增/编辑回访记录 ====================
const visitFormDrawerVisible = ref(false)
const visitDialogType = ref<'add' | 'edit'>('add')
const visitFormRef = ref<FormInstance>()
const visitSubmitLoading = ref(false)
const visitForm = ref({
id: 0, fan_id: 0, visit_type: 1, visit_time: '', content: '', result: '', next_visit_time: ''
})
const visitRules: FormRules = {
visit_type: [{ required: true, message: '请选择回访类型', trigger: 'change' }],
visit_time: [{ required: true, message: '请选择回访时间', trigger: 'change' }],
content: [{ required: true, message: '请输入回访内容', trigger: 'blur' }]
}
const handleAddVisitRecord = () => {
visitDialogType.value = 'add'
visitForm.value = {
id: 0, fan_id: currentFan.value.id, visit_type: 1,
visit_time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
content: '', result: '', next_visit_time: ''
}
visitFormDrawerVisible.value = true
}
const handleEditVisitRecord = (row: any) => {
visitDialogType.value = 'edit'
visitForm.value = {
id: row.id, fan_id: row.fan_id, visit_type: row.visit_type,
visit_time: row.visit_time_text || '', content: row.content || '',
result: row.result || '', next_visit_time: row.next_visit_time_text || ''
}
visitFormDrawerVisible.value = true
}
const resetVisitForm = () => {
visitForm.value = { id: 0, fan_id: 0, visit_type: 1, visit_time: '', content: '', result: '', next_visit_time: '' }
visitFormRef.value?.resetFields()
}
const handleVisitSubmit = async () => {
await visitFormRef.value?.validate()
visitSubmitLoading.value = true
try {
if (visitDialogType.value === 'add') {
await fanVisitRecordAdd(visitForm.value)
} else {
await fanVisitRecordEdit(visitForm.value)
}
visitFormDrawerVisible.value = false
visitPageNo.value = 1
loadVisitRecords()
} catch (error: any) {
} finally {
visitSubmitLoading.value = false
}
}
const handleDeleteVisitRecord = async (id: number) => {
await feedback.confirm('确定删除该回访记录吗?')
try {
await fanVisitRecordDelete({ id })
visitPageNo.value = 1
loadVisitRecords()
} catch (error: any) {
}
}
loadList()
</script>
<style lang="scss" scoped>
.fans-h5 {
max-width: 500px;
margin: 0 auto;
min-height: 100vh;
background: #f5f6fa;
padding-bottom: 80px;
}
.h5-header {
background: #fff;
padding: 12px 16px;
position: sticky;
top: 0;
z-index: 10;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}
.h5-search {
margin-bottom: 8px;
}
.h5-filter-row {
display: flex;
gap: 8px;
align-items: center;
.el-select {
width: 80px;
}
}
.h5-list {
padding: 12px 16px;
}
.h5-card {
background: #fff;
border-radius: 12px;
margin-bottom: 12px;
overflow: hidden;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
}
.h5-card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 16px 0;
}
.h5-card-name {
display: flex;
align-items: center;
gap: 8px;
.name {
font-size: 16px;
font-weight: 600;
color: #303133;
}
.age {
font-size: 12px;
color: #909399;
}
}
.h5-card-body {
padding: 10px 16px;
}
.info-line {
display: flex;
font-size: 13px;
line-height: 2;
.label {
color: #909399;
width: 50px;
flex-shrink: 0;
}
.value {
color: #606266;
flex: 1;
&.remark {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.h5-card-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 16px;
border-top: 1px solid #f2f3f5;
.footer-left {
display: flex;
flex-direction: column;
gap: 2px;
}
.visit-info {
font-size: 12px;
color: #909399;
}
.visit-count {
color: #67c23a;
font-weight: 600;
font-size: 14px;
}
.creator-info {
font-size: 11px;
color: #b0b3b8;
}
}
.h5-fab {
position: fixed;
right: 20px;
bottom: 40px;
width: 50px;
height: 50px;
border-radius: 50%;
background: linear-gradient(135deg, #409eff 0%, #337ecc 100%);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
box-shadow: 0 4px 16px rgba(64, 158, 255, 0.4);
cursor: pointer;
z-index: 99;
transition: transform 0.2s;
&:active {
transform: scale(0.9);
}
}
.h5-load-more {
text-align: center;
padding: 16px;
font-size: 13px;
color: #409eff;
cursor: pointer;
}
.h5-no-more {
text-align: center;
padding: 16px;
font-size: 12px;
color: #c0c4cc;
}
.h5-empty {
padding: 40px 0;
}
.h5-form {
:deep(.el-form-item__label) {
font-weight: 500;
}
}
.h5-form-row {
display: flex;
gap: 12px;
}
.h5-radio-group {
display: flex;
flex-wrap: wrap;
gap: 0;
}
// 回访记录
.h5-visit-header {
margin-bottom: 12px;
}
.h5-visit-list {
padding: 0;
}
.h5-visit-card {
background: #f9fafb;
border-radius: 10px;
padding: 14px;
margin-bottom: 10px;
border-left: 3px solid #409eff;
}
.visit-card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.visit-card-tags {
display: flex;
align-items: center;
gap: 8px;
.visit-time {
font-size: 12px;
color: #909399;
}
}
.visit-card-content {
font-size: 14px;
color: #303133;
line-height: 1.6;
margin-bottom: 6px;
}
.visit-card-result {
font-size: 13px;
color: #606266;
margin-bottom: 6px;
.label {
color: #909399;
}
}
.visit-card-meta {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #909399;
.next-visit {
color: #e6a23c;
}
}
// 抽屉底部按钮
:deep(.el-drawer__footer) {
display: flex;
gap: 12px;
padding: 12px 16px;
border-top: 1px solid #f2f3f5;
}
</style>
+513
View File
@@ -0,0 +1,513 @@
<template>
<div class="fans-management">
<!-- 搜索区域 -->
<el-card class="!border-none" shadow="never">
<el-form class="ls-form" :model="formData" inline>
<el-form-item class="w-[280px]" label="姓名">
<el-input
placeholder="请输入姓名"
v-model="formData.name"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item class="w-[280px]" label="手机号">
<el-input
placeholder="请输入手机号"
v-model="formData.phone"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item class="w-[180px]" label="性别">
<el-select v-model="formData.gender" placeholder="请选择" clearable>
<el-option label="男" :value="1" />
<el-option label="女" :value="2" />
</el-select>
</el-form-item>
<el-form-item class="w-[180px]" label="状态">
<el-select v-model="formData.status" placeholder="请选择" clearable>
<el-option label="启用" :value="1" />
<el-option label="禁用" :value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 列表区域 -->
<el-card class="!border-none mt-4" shadow="never">
<div class="mb-4">
<el-button type="primary" @click="handleAdd">新增粉丝</el-button>
</div>
<el-table :data="pager.lists" size="large" v-loading="pager.loading">
<el-table-column label="ID" prop="id" width="70" />
<el-table-column label="姓名" prop="name" min-width="100" />
<el-table-column label="手机号" prop="phone" min-width="130" />
<el-table-column label="身份证号" prop="id_card" min-width="180" />
<el-table-column label="性别" prop="gender_desc" width="80" />
<el-table-column label="年龄" prop="age" width="70" />
<el-table-column label="备注" prop="remark" min-width="150" show-overflow-tooltip />
<el-table-column label="登记人" prop="creator_name" min-width="100">
<template #default="{ row }">
<span>{{ row.creator_name || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="回访次数" width="90" align="center">
<template #default="{ row }">
<el-tag v-if="row.visit_count > 0" type="success">{{ row.visit_count }}</el-tag>
<span v-else class="text-gray-400">0</span>
</template>
</el-table-column>
<el-table-column label="状态" width="80">
<template #default="{ row }">
<el-tag v-if="row.status == 1" type="success">启用</el-tag>
<el-tag v-else type="danger">禁用</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" min-width="170">
<template #default="{ row }">
<span>{{ formatDateTime(row.create_time) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="220" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
<el-button type="success" link @click="handleVisitRecords(row)">回访记录</el-button>
<el-button type="danger" link @click="handleDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<!-- 新增/编辑粉丝弹窗 -->
<el-dialog
v-model="fanDialogVisible"
:title="fanDialogType === 'add' ? '新增粉丝' : '编辑粉丝'"
width="600px"
:close-on-click-modal="false"
@closed="resetFanForm"
>
<el-form
ref="fanFormRef"
:model="fanForm"
:rules="fanRules"
label-width="100px"
>
<el-form-item label="姓名" prop="name">
<el-input v-model="fanForm.name" placeholder="请输入姓名" maxlength="50" />
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="fanForm.phone" placeholder="请输入手机号" maxlength="11" />
</el-form-item>
<el-form-item label="身份证号" prop="id_card">
<el-input v-model="fanForm.id_card" placeholder="请输入身份证号码" maxlength="18" />
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input-number v-model="fanForm.age" :min="0" :max="150" />
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-radio-group v-model="fanForm.gender">
<el-radio :label="1"></el-radio>
<el-radio :label="2"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="fanForm.status">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="fanForm.remark"
type="textarea"
:rows="3"
placeholder="请输入备注"
maxlength="500"
show-word-limit
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="fanDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="fanSubmitLoading" @click="handleFanSubmit">确定</el-button>
</template>
</el-dialog>
<!-- 回访记录抽屉 -->
<el-drawer
v-model="visitDrawerVisible"
:title="`回访记录 - ${currentFan?.name || ''}`"
size="700px"
:close-on-click-modal="false"
>
<div class="mb-4">
<el-button type="primary" @click="handleAddVisitRecord">新增回访记录</el-button>
</div>
<el-table :data="visitRecords" size="large" v-loading="visitLoading">
<el-table-column label="回访类型" width="100">
<template #default="{ row }">
<el-tag :type="visitTypeTagMap[row.visit_type]">
{{ row.visit_type_desc }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="回访时间" prop="visit_time_text" min-width="150" />
<el-table-column label="回访内容" prop="content" min-width="200" show-overflow-tooltip />
<el-table-column label="回访结果" prop="result" min-width="150" show-overflow-tooltip />
<el-table-column label="下次回访" prop="next_visit_time_text" min-width="150" />
<el-table-column label="操作人" prop="operator_name" width="100" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEditVisitRecord(row)">编辑</el-button>
<el-button type="danger" link @click="handleDeleteVisitRecord(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="visitTotal > visitRecords.length" class="text-center mt-4">
<el-button link type="primary" @click="loadMoreVisitRecords">加载更多</el-button>
</div>
</el-drawer>
<!-- 新增/编辑回访记录弹窗 -->
<el-dialog
v-model="visitDialogVisible"
:title="visitDialogType === 'add' ? '新增回访记录' : '编辑回访记录'"
width="600px"
:close-on-click-modal="false"
@closed="resetVisitForm"
>
<el-form
ref="visitFormRef"
:model="visitForm"
:rules="visitRules"
label-width="120px"
>
<el-form-item label="回访类型" prop="visit_type">
<el-select v-model="visitForm.visit_type" placeholder="请选择回访类型">
<el-option label="电话" :value="1" />
<el-option label="微信" :value="2" />
<el-option label="短信" :value="3" />
<el-option label="上门" :value="4" />
<el-option label="其他" :value="5" />
</el-select>
</el-form-item>
<el-form-item label="回访时间" prop="visit_time">
<el-date-picker
v-model="visitForm.visit_time"
type="datetime"
placeholder="请选择回访时间"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="回访内容" prop="content">
<el-input
v-model="visitForm.content"
type="textarea"
:rows="4"
placeholder="请输入回访内容"
/>
</el-form-item>
<el-form-item label="回访结果" prop="result">
<el-input
v-model="visitForm.result"
type="textarea"
:rows="3"
placeholder="请输入回访结果"
/>
</el-form-item>
<el-form-item label="下次回访时间" prop="next_visit_time">
<el-date-picker
v-model="visitForm.next_visit_time"
type="datetime"
placeholder="请选择下次回访时间"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="visitDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="visitSubmitLoading" @click="handleVisitSubmit">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts" name="fansManagement">
import {
fanLists,
fanAdd,
fanEdit,
fanDelete,
fanVisitRecordLists,
fanVisitRecordAdd,
fanVisitRecordEdit,
fanVisitRecordDelete
} from '@/api/fans'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import dayjs from 'dayjs'
import type { FormInstance, FormRules } from 'element-plus'
const formatDateTime = (timestamp: number | string) => {
if (!timestamp) return '-'
const ts = String(timestamp).length === 10 ? Number(timestamp) * 1000 : Number(timestamp)
return dayjs(ts).format('YYYY-MM-DD HH:mm:ss')
}
// ==================== 粉丝列表 ====================
const formData = ref({
name: '',
phone: '',
gender: '' as string | number,
status: '' as string | number
})
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: fanLists,
params: formData.value
})
// ==================== 新增/编辑粉丝 ====================
const fanDialogVisible = ref(false)
const fanDialogType = ref<'add' | 'edit'>('add')
const fanFormRef = ref<FormInstance>()
const fanSubmitLoading = ref(false)
const fanForm = ref({
id: 0,
name: '',
phone: '',
id_card: '',
age: 0,
gender: 1,
status: 1,
remark: ''
})
const fanRules: FormRules = {
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
],
id_card: [
{ pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '身份证号格式不正确', trigger: 'blur' }
],
gender: [{ required: true, message: '请选择性别', trigger: 'change' }]
}
const handleAdd = () => {
fanDialogType.value = 'add'
fanDialogVisible.value = true
}
const handleEdit = (row: any) => {
fanDialogType.value = 'edit'
fanForm.value = {
id: row.id,
name: row.name,
phone: row.phone,
id_card: row.id_card,
age: row.age,
gender: row.gender,
status: row.status,
remark: row.remark
}
fanDialogVisible.value = true
}
const resetFanForm = () => {
fanForm.value = {
id: 0,
name: '',
phone: '',
id_card: '',
age: 0,
gender: 1,
status: 1,
remark: ''
}
fanFormRef.value?.resetFields()
}
const handleFanSubmit = async () => {
await fanFormRef.value?.validate()
fanSubmitLoading.value = true
try {
if (fanDialogType.value === 'add') {
await fanAdd(fanForm.value)
} else {
await fanEdit(fanForm.value)
}
fanDialogVisible.value = false
getLists()
} catch (error: any) {
} finally {
fanSubmitLoading.value = false
}
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除该粉丝吗?')
try {
await fanDelete({ id })
getLists()
} catch (error: any) {
}
}
// ==================== 回访记录 ====================
const visitDrawerVisible = ref(false)
const currentFan = ref<any>(null)
const visitRecords = ref<any[]>([])
const visitLoading = ref(false)
const visitTotal = ref(0)
const visitPageNo = ref(1)
const visitTypeTagMap: Record<number, string> = {
1: '',
2: 'success',
3: 'info',
4: 'warning',
5: 'danger'
}
const handleVisitRecords = (row: any) => {
currentFan.value = row
visitDrawerVisible.value = true
visitPageNo.value = 1
visitRecords.value = []
loadVisitRecords()
}
const loadVisitRecords = async () => {
visitLoading.value = true
try {
const res = await fanVisitRecordLists({
fan_id: currentFan.value.id,
page_no: visitPageNo.value,
page_size: 15
})
if (visitPageNo.value === 1) {
visitRecords.value = res.lists || []
} else {
visitRecords.value = [...visitRecords.value, ...(res.lists || [])]
}
visitTotal.value = res.count || 0
} catch (error) {
console.error('获取回访记录失败:', error)
} finally {
visitLoading.value = false
}
}
const loadMoreVisitRecords = () => {
visitPageNo.value++
loadVisitRecords()
}
// ==================== 新增/编辑回访记录 ====================
const visitDialogVisible = ref(false)
const visitDialogType = ref<'add' | 'edit'>('add')
const visitFormRef = ref<FormInstance>()
const visitSubmitLoading = ref(false)
const visitForm = ref({
id: 0,
fan_id: 0,
visit_type: 1,
visit_time: '',
content: '',
result: '',
next_visit_time: ''
})
const visitRules: FormRules = {
visit_type: [{ required: true, message: '请选择回访类型', trigger: 'change' }],
visit_time: [{ required: true, message: '请选择回访时间', trigger: 'change' }],
content: [{ required: true, message: '请输入回访内容', trigger: 'blur' }]
}
const handleAddVisitRecord = () => {
visitDialogType.value = 'add'
visitForm.value = {
id: 0,
fan_id: currentFan.value.id,
visit_type: 1,
visit_time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
content: '',
result: '',
next_visit_time: ''
}
visitDialogVisible.value = true
}
const handleEditVisitRecord = (row: any) => {
visitDialogType.value = 'edit'
visitForm.value = {
id: row.id,
fan_id: row.fan_id,
visit_type: row.visit_type,
visit_time: row.visit_time_text || '',
content: row.content || '',
result: row.result || '',
next_visit_time: row.next_visit_time_text || ''
}
visitDialogVisible.value = true
}
const resetVisitForm = () => {
visitForm.value = {
id: 0,
fan_id: 0,
visit_type: 1,
visit_time: '',
content: '',
result: '',
next_visit_time: ''
}
visitFormRef.value?.resetFields()
}
const handleVisitSubmit = async () => {
await visitFormRef.value?.validate()
visitSubmitLoading.value = true
try {
if (visitDialogType.value === 'add') {
await fanVisitRecordAdd(visitForm.value)
} else {
await fanVisitRecordEdit(visitForm.value)
}
visitDialogVisible.value = false
visitPageNo.value = 1
loadVisitRecords()
} catch (error: any) {
} finally {
visitSubmitLoading.value = false
}
}
const handleDeleteVisitRecord = async (id: number) => {
await feedback.confirm('确定要删除该回访记录吗?')
try {
await fanVisitRecordDelete({ id })
visitPageNo.value = 1
loadVisitRecords()
} catch (error: any) {
}
}
getLists()
</script>
+76
View File
@@ -135,6 +135,13 @@
> >
详情 详情
</el-button> </el-button>
<el-button
type="primary"
link
@click="handleOrderQrcode(row)"
>
小程序码
</el-button>
<el-button <el-button
v-if="row.status === 1" v-if="row.status === 1"
v-perms="['order.order/pay']" v-perms="['order.order/pay']"
@@ -337,12 +344,46 @@
</el-button> </el-button>
</template> </template>
</el-dialog> </el-dialog>
<!-- 小程序码弹窗 -->
<el-dialog
v-model="qrcodeDialogVisible"
title="支付小程序码"
width="400px"
:close-on-click-modal="false"
>
<div class="flex flex-col items-center justify-center py-4">
<div v-if="qrcodeLoading" class="text-center">
<el-icon class="is-loading" :size="40">
<Loading />
</el-icon>
<div class="mt-4 text-gray-500">生成中...</div>
</div>
<div v-else-if="qrcodeUrl" class="text-center">
<img :src="qrcodeUrl" alt="小程序二维码" class="w-64 h-64 border border-gray-200 rounded" />
<div class="mt-4 text-sm text-gray-600">
<div>订单号{{ qrcodeOrderNo }}</div>
<div class="mt-2">请使用微信扫描二维码完成支付</div>
</div>
</div>
<div v-else class="text-center text-gray-500">
生成失败请重试
</div>
</div>
<template #footer>
<el-button @click="qrcodeDialogVisible = false">关闭</el-button>
<el-button v-if="!qrcodeLoading" type="primary" @click="handleOrderQrcodeRefresh">
重新生成
</el-button>
</template>
</el-dialog>
</div> </div>
</template> </template>
<script setup lang="ts" name="orderList"> <script setup lang="ts" name="orderList">
import { usePaging } from '@/hooks/usePaging' import { usePaging } from '@/hooks/usePaging'
import { orderLists, orderDetail, orderPay, orderCancel, orderDelete, orderRefund, orderExport, orderCreate, searchPatients as searchPatientsAPI, alipayPay, wechatPay } from '@/api/order' import { orderLists, orderDetail, orderPay, orderCancel, orderDelete, orderRefund, orderExport, orderCreate, searchPatients as searchPatientsAPI, alipayPay, wechatPay } from '@/api/order'
import { generateOrderQrcode } from '@/api/tcm'
import { Loading } from '@element-plus/icons-vue'
import feedback from '@/utils/feedback' import feedback from '@/utils/feedback'
const queryParams = reactive({ const queryParams = reactive({
@@ -638,6 +679,41 @@ const handleDelete = async (row: any) => {
} }
} }
// 小程序码相关
const qrcodeDialogVisible = ref(false)
const qrcodeLoading = ref(false)
const qrcodeUrl = ref('')
const qrcodeOrderNo = ref('')
const handleOrderQrcode = async (row: any) => {
if (!row.order_no) {
feedback.msgWarning('订单号不存在')
return
}
qrcodeOrderNo.value = row.order_no
qrcodeDialogVisible.value = true
qrcodeLoading.value = true
qrcodeUrl.value = ''
try {
const res = await generateOrderQrcode({ order_no: row.order_no })
if (res?.qrcode_url) {
qrcodeUrl.value = res.qrcode_url
} else {
feedback.msgError('二维码生成失败')
}
} catch (e: any) {
feedback.msgError(e?.msg || '生成二维码失败')
} finally {
qrcodeLoading.value = false
}
}
const handleOrderQrcodeRefresh = () => {
if (qrcodeOrderNo.value) {
handleOrderQrcode({ order_no: qrcodeOrderNo.value })
}
}
onMounted(() => { onMounted(() => {
getLists() getLists()
}) })
+2 -2
View File
@@ -170,7 +170,7 @@
link link
@click="handleComplete(row)" @click="handleComplete(row)"
> >
完成面诊 接诊完成
</el-button> </el-button>
<el-button <el-button
v-if="row.status === 1" v-if="row.status === 1"
@@ -188,7 +188,7 @@
link link
@click="handleMiniProgramQRCode(row)" @click="handleMiniProgramQRCode(row)"
> >
确认诊单二维码 视频二维码
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
+15 -5
View File
@@ -21,16 +21,16 @@
<!-- 基本信息 --> <!-- 基本信息 -->
<el-divider content-position="left">基本信息</el-divider> <el-divider content-position="left">基本信息</el-divider>
<el-form-item label="患者ID"> <el-form-item label="诊单ID">
<el-input v-model="formData.patient_id" disabled placeholder="系统自动生成" /> <el-input v-model="formData.patient_id" disabled placeholder="系统自动生成" />
</el-form-item> </el-form-item>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="患者姓名" prop="patient_name"> <el-form-item label="姓名" prop="patient_name">
<el-input <el-input
v-model="formData.patient_name" v-model="formData.patient_name"
placeholder="请输入患者姓名" placeholder="请输入姓名"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -94,6 +94,7 @@
</el-col> </el-col>
</el-row> </el-row>
<!-- 生命体征 --> <!-- 生命体征 -->
<el-divider content-position="left">生命体征</el-divider> <el-divider content-position="left">生命体征</el-divider>
@@ -589,6 +590,7 @@
</div> </div>
</template> </template>
</el-drawer> </el-drawer>
</div> </div>
</template> </template>
@@ -596,7 +598,9 @@
import { tcmDiagnosisAdd, tcmDiagnosisEdit, tcmDiagnosisDetail, checkPhone, checkIdCard } from '@/api/tcm' import { tcmDiagnosisAdd, tcmDiagnosisEdit, tcmDiagnosisDetail, checkPhone, checkIdCard } from '@/api/tcm'
import { getDictData } from '@/api/app' import { getDictData } from '@/api/app'
import feedback from '@/utils/feedback' import feedback from '@/utils/feedback'
import useUserStore from '@/stores/modules/user'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { QuestionFilled } from '@element-plus/icons-vue'
import BloodRecordList from './components/BloodRecordList.vue' import BloodRecordList from './components/BloodRecordList.vue'
const emit = defineEmits(['success']) const emit = defineEmits(['success'])
@@ -659,7 +663,8 @@ const formData = ref({
prescription: '', prescription: '',
doctor_advice: '', doctor_advice: '',
remark: '', remark: '',
status: 1 status: 1,
external_userid: ''
}) })
// 自定义验证规则 // 自定义验证规则
@@ -832,6 +837,9 @@ const open = async (type: string, id?: number) => {
if (type === 'edit' && id) { if (type === 'edit' && id) {
const data = await tcmDiagnosisDetail({ id }) const data = await tcmDiagnosisDetail({ id })
formData.value = data formData.value = data
} else if (type === 'add') {
const userStore = useUserStore()
formData.value.assistant_id = userStore.userInfo?.id || ''
} }
} }
@@ -917,7 +925,8 @@ const handleClose = () => {
prescription: '', prescription: '',
doctor_advice: '', doctor_advice: '',
remark: '', remark: '',
status: 1 status: 1,
external_userid: ''
} }
visible.value = false visible.value = false
} }
@@ -1082,4 +1091,5 @@ defineExpose({
.el-select-dropdown { .el-select-dropdown {
z-index: 3000 !important; z-index: 3000 !important;
} }
</style> </style>
+381 -8
View File
@@ -76,8 +76,9 @@
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
> >
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column label="账户编号" prop="id" width="80" /> <el-table-column label="账户编号" prop="id" width="90" />
<el-table-column label="账户姓名" prop="patient_name" min-width="100" /> <el-table-column label="账户姓名" prop="patient_name" min-width="100" />
<el-table-column label="性别" prop="gender_desc" width="80" /> <el-table-column label="性别" prop="gender_desc" width="80" />
<el-table-column label="年龄" prop="age" width="80" /> <el-table-column label="年龄" prop="age" width="80" />
<el-table-column label="诊断日期" prop="diagnosis_date_text" min-width="120" /> <el-table-column label="诊断日期" prop="diagnosis_date_text" min-width="120" />
@@ -86,6 +87,12 @@
<span>{{ getDictLabel(diagnosisTypeOptions, row.diagnosis_type) }}</span> <span>{{ getDictLabel(diagnosisTypeOptions, row.diagnosis_type) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="确认诊单" min-width="100">
<template #default="{ row }">
<el-tag v-if="row.DiagnosisViewRecord && row.DiagnosisViewRecord.length > 0" type="success" size="small">已确认</el-tag>
<el-tag v-else type="info" size="small">未确认</el-tag>
</template>
</el-table-column>
<el-table-column label="证型" prop="syndrome_type" min-width="100"> <el-table-column label="证型" prop="syndrome_type" min-width="100">
<template #default="{ row }"> <template #default="{ row }">
<span>{{ getDictLabel(syndromeTypeOptions, row.syndrome_type) }}</span> <span>{{ getDictLabel(syndromeTypeOptions, row.syndrome_type) }}</span>
@@ -96,22 +103,22 @@
<span>{{ getAssistantName(row.assistant_id || row.assistant) }}</span> <span>{{ getAssistantName(row.assistant_id || row.assistant) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" width="80"> <!-- <el-table-column label="状态" width="80">
<template #default="{ row }"> <template #default="{ row }">
<el-tag v-if="row.status == 1" type="success">启用</el-tag> <el-tag v-if="row.status == 1" type="success">启用</el-tag>
<el-tag v-else type="danger">禁用</el-tag> <el-tag v-else type="danger">禁用</el-tag>
</template> </template>
</el-table-column> </el-table-column> -->
<el-table-column label="创建时间" prop="create_time" min-width="160"> <el-table-column label="创建时间" prop="create_time" min-width="160">
<template #default="{ row }"> <template #default="{ row }">
<span>{{ formatDateTime(row.create_time) }}</span> <span>{{ formatDateTime(row.create_time) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="240" fixed="right"> <el-table-column label="操作" width="300" fixed="right">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="primary" link @click="handleDetail(row.id)"> <!-- <el-button type="primary" link @click="handleDetail(row.id)">
查看 查看
</el-button> </el-button> -->
<el-button <el-button
v-perms="['tcm.diagnosis/assign']" v-perms="['tcm.diagnosis/assign']"
type="success" type="success"
@@ -155,6 +162,12 @@
<el-button type="primary" link @click="handleEdit(row.id)" v-perms="['tcm.diagnosis/edit']"> <el-button type="primary" link @click="handleEdit(row.id)" v-perms="['tcm.diagnosis/edit']">
诊单 诊单
</el-button> </el-button>
<!-- <el-button type="primary" link @click="handleWechatRecords(row)">
企微记录
</el-button> -->
<el-button type="primary" link @click="handleCreateOrder(row)">
创建订单
</el-button>
<el-button type="danger" link @click="handleDelete(row.id)" v-perms="['tcm.diagnosis/delete']"> <el-button type="danger" link @click="handleDelete(row.id)" v-perms="['tcm.diagnosis/delete']">
删除 删除
</el-button> </el-button>
@@ -248,11 +261,170 @@
</el-button> </el-button>
</template> </template>
</el-dialog> </el-dialog>
<!-- 创建订单弹窗 -->
<el-dialog
v-model="createOrderVisible"
title="创建订单"
width="600px"
@close="resetOrderForm"
>
<el-form
ref="orderFormRef"
:model="orderForm"
:rules="orderRules"
label-width="100px"
>
<el-form-item label="患者">
<span class="font-medium">{{ orderForm.patient_name }} ({{ orderForm.phone }})</span>
</el-form-item>
<el-form-item label="订单类型" prop="order_type">
<el-select v-model="orderForm.order_type" placeholder="请选择" class="w-full">
<el-option label="挂号费" :value="1" />
<el-option label="问诊费" :value="2" />
<el-option label="药品费用" :value="3" />
</el-select>
</el-form-item>
<el-form-item label="订单金额" prop="amount">
<el-input-number
v-model="orderForm.amount"
:min="0"
:step="0.01"
:precision="2"
placeholder="请输入金额"
class="w-full"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="orderForm.remark"
type="textarea"
:rows="3"
placeholder="请输入备注(可选)"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="createOrderVisible = false">取消</el-button>
<el-button type="primary" @click="submitOrder" :loading="orderLoading">创建订单</el-button>
</template>
</el-dialog>
<!-- 企业微信聊天记录抽屉 -->
<el-drawer
v-model="wechatDrawerVisible"
:title="`企业微信记录 - ${wechatCurrentPatient?.patient_name || ''}`"
size="600px"
:destroy-on-close="true"
>
<!-- 患者与企微信息 -->
<div v-if="wechatContactInfo" class="mb-4">
<el-descriptions :column="2" border size="small">
<el-descriptions-item label="患者姓名">{{ wechatCurrentPatient?.patient_name }}</el-descriptions-item>
<el-descriptions-item label="手机号">{{ wechatContactInfo.phone || '-' }}</el-descriptions-item>
<el-descriptions-item label="企微联系人ID">
<span v-if="wechatContactInfo.external_userid">{{ wechatContactInfo.external_userid }}</span>
<el-tag v-else type="info" size="small">未关联</el-tag>
</el-descriptions-item>
<el-descriptions-item label="会话存档">
<el-tag v-if="wechatContactInfo.msgaudit_enabled" type="success" size="small">已开通</el-tag>
<el-tag v-else type="info" size="small">未配置</el-tag>
</el-descriptions-item>
</el-descriptions>
<!-- 存档成员列表 -->
<div v-if="wechatContactInfo.permit_users?.length" class="mt-2">
<span class="text-sm text-gray-500 mr-2">存档成员</span>
<el-tag
v-for="uid in wechatContactInfo.permit_users"
:key="uid"
size="small"
class="mr-1"
>
{{ uid }}
</el-tag>
</div>
<!-- 同意存档情况 -->
<div v-if="wechatContactInfo.msgaudit_agree?.length" class="mt-2">
<span class="text-sm text-gray-500 mr-2">存档同意</span>
<el-tag
v-for="(info, idx) in wechatContactInfo.msgaudit_agree"
:key="idx"
:type="info.agree_status === 'Agree' ? 'success' : 'warning'"
size="small"
class="mr-1"
>
{{ info.userid }}: {{ info.agree_status === 'Agree' ? '已同意' : info.agree_status }}
</el-tag>
</div>
</div>
<el-divider />
<!-- 添加记录 -->
<div class="mb-4">
<div class="flex gap-2">
<el-input
v-model="wechatNewNote"
type="textarea"
:rows="2"
placeholder="添加沟通记录..."
class="flex-1"
/>
<el-button type="primary" @click="handleAddRecord" :loading="wechatAddLoading" class="self-end">
添加
</el-button>
</div>
</div>
<!-- 记录列表 -->
<div v-loading="wechatRecordsLoading">
<div v-if="wechatRecords.length === 0" class="text-center text-gray-400 py-10">
暂无聊天记录
</div>
<div v-else class="record-list">
<div
v-for="record in wechatRecords"
:key="record.id"
class="record-item"
>
<div class="record-header">
<div class="flex items-center gap-2">
<el-tag :type="record.direction === 0 ? 'primary' : 'success'" size="small">
{{ record.direction === 0 ? '员工' : '客户' }}
</el-tag>
<span class="font-medium text-sm">
{{ record.direction === 0 ? record.staff_name : record.external_name || wechatCurrentPatient?.patient_name }}
</span>
<el-tag v-if="record.msg_type === 'note'" type="warning" size="small">备注</el-tag>
</div>
<div class="flex items-center gap-2">
<span class="text-xs text-gray-400">{{ formatTimestamp(record.chat_time) }}</span>
<el-button type="danger" link size="small" @click="handleDeleteRecord(record.id)">
删除
</el-button>
</div>
</div>
<div class="record-content">{{ record.content }}</div>
<div v-if="record.media_url" class="mt-1">
<el-image :src="record.media_url" style="max-width: 200px" fit="contain" :preview-src-list="[record.media_url]" />
</div>
</div>
</div>
<div v-if="wechatRecordTotal > wechatRecords.length" class="text-center mt-4">
<el-button link type="primary" @click="loadMoreRecords">加载更多</el-button>
</div>
</div>
</el-drawer>
</div> </div>
</template> </template>
<script setup lang="ts" name="tcmDiagnosis"> <script setup lang="ts" name="tcmDiagnosis">
import { tcmDiagnosisLists, tcmDiagnosisDelete, tcmDiagnosisAssign, getAssistants, generateMiniProgramQrcode } from '@/api/tcm' import { tcmDiagnosisLists, tcmDiagnosisDelete, tcmDiagnosisAssign, getAssistants, generateMiniProgramQrcode, generateOrderQrcode, getWechatChatRecords, addWechatChatRecord, deleteWechatChatRecord, getWechatExternalContact } from '@/api/tcm'
import { orderCreate } from '@/api/order'
import { usePaging } from '@/hooks/usePaging' import { usePaging } from '@/hooks/usePaging'
import { getDictData } from '@/api/app' import { getDictData } from '@/api/app'
import { getWeappConfig } from '@/api/channel/weapp' import { getWeappConfig } from '@/api/channel/weapp'
@@ -340,6 +512,83 @@ const detailRef = ref()
const appointmentRef = ref() const appointmentRef = ref()
const userStore = useUserStore() const userStore = useUserStore()
// 创建订单相关
const createOrderVisible = ref(false)
const orderFormRef = ref()
const orderLoading = ref(false)
const orderForm = reactive({
patient_id: '' as string | number,
patient_name: '',
phone: '',
order_type: '' as string | number,
amount: 0,
remark: ''
})
const orderRules = {
order_type: [{ required: true, message: '请选择订单类型', trigger: 'change' }],
amount: [{ required: true, message: '请输入订单金额', trigger: 'blur' }]
}
const handleCreateOrder = (row: any) => {
orderForm.patient_id = row.patient_id || row.id
orderForm.patient_name = row.patient_name
orderForm.phone = row.phone || ''
orderForm.order_type = ''
orderForm.amount = 0
orderForm.remark = ''
orderFormRef.value?.clearValidate()
createOrderVisible.value = true
}
const resetOrderForm = () => {
orderForm.patient_id = ''
orderForm.patient_name = ''
orderForm.phone = ''
orderForm.order_type = ''
orderForm.amount = 0
orderForm.remark = ''
orderFormRef.value?.clearValidate()
}
const submitOrder = async () => {
try {
await orderFormRef.value?.validate()
orderLoading.value = true
const res = await orderCreate({
patient_id: orderForm.patient_id,
order_type: orderForm.order_type,
amount: orderForm.amount,
remark: orderForm.remark
})
createOrderVisible.value = false
getLists()
const orderNo = res?.order_no
if (orderNo) {
qrcodeDialogVisible.value = true
qrcodeLoading.value = true
qrcodeUrl.value = ''
currentQRCodePatient.value = { patient_name: orderForm.patient_name }
try {
const qrRes = await generateOrderQrcode({ order_no: orderNo })
if (qrRes?.qrcode_url) {
qrcodeUrl.value = qrRes.qrcode_url
} else {
feedback.msgError('二维码生成失败')
}
} catch (e: any) {
feedback.msgError(e?.msg || '生成二维码失败')
} finally {
qrcodeLoading.value = false
}
}
} catch (error) {
console.error('创建订单失败:', error)
} finally {
orderLoading.value = false
}
}
// 小程序二维码相关 // 小程序二维码相关
const qrcodeDialogVisible = ref(false) const qrcodeDialogVisible = ref(false)
const qrcodeLoading = ref(false) const qrcodeLoading = ref(false)
@@ -502,10 +751,134 @@ const handleRegenerateQRCode = () => {
} }
} }
// ========== 企业微信聊天记录 ==========
const wechatDrawerVisible = ref(false)
const wechatCurrentPatient = ref<any>(null)
const wechatRecords = ref<any[]>([])
const wechatRecordTotal = ref(0)
const wechatRecordsLoading = ref(false)
const wechatContactInfo = ref<any>(null)
const wechatNewNote = ref('')
const wechatAddLoading = ref(false)
const wechatPage = ref(1)
const formatTimestamp = (ts: number) => {
if (!ts) return '-'
const t = String(ts).length === 10 ? ts * 1000 : ts
return dayjs(t).format('YYYY-MM-DD HH:mm')
}
const handleWechatRecords = async (row: any) => {
wechatCurrentPatient.value = row
wechatDrawerVisible.value = true
wechatRecords.value = []
wechatRecordTotal.value = 0
wechatContactInfo.value = null
wechatNewNote.value = ''
wechatPage.value = 1
// 并行加载聊天记录和外部联系人信息
wechatRecordsLoading.value = true
try {
const [recordsRes, contactRes] = await Promise.all([
getWechatChatRecords({ diagnosis_id: row.id, patient_id: row.patient_id, page_no: 1, page_size: 20 }),
getWechatExternalContact({ patient_id: row.patient_id || row.id }).catch(() => null)
])
wechatRecords.value = recordsRes?.lists || []
wechatRecordTotal.value = recordsRes?.count || 0
wechatContactInfo.value = contactRes
} catch (e) {
console.error('加载企业微信记录失败:', e)
} finally {
wechatRecordsLoading.value = false
}
}
const loadMoreRecords = async () => {
if (!wechatCurrentPatient.value) return
wechatPage.value++
try {
const res = await getWechatChatRecords({
diagnosis_id: wechatCurrentPatient.value.id,
patient_id: wechatCurrentPatient.value.patient_id,
page_no: wechatPage.value,
page_size: 20
})
wechatRecords.value.push(...(res?.lists || []))
} catch (e) {
console.error('加载更多记录失败:', e)
}
}
const handleAddRecord = async () => {
if (!wechatNewNote.value.trim()) {
feedback.msgWarning('请输入内容')
return
}
wechatAddLoading.value = true
try {
await addWechatChatRecord({
diagnosis_id: wechatCurrentPatient.value.id,
patient_id: wechatCurrentPatient.value.patient_id,
content: wechatNewNote.value.trim(),
msg_type: 'note',
staff_name: userStore.userInfo?.name || '',
external_name: wechatCurrentPatient.value.patient_name || '',
})
wechatNewNote.value = ''
// 重新加载记录
handleWechatRecords(wechatCurrentPatient.value)
} catch (e: any) {
feedback.msgError(e?.msg || '添加失败')
} finally {
wechatAddLoading.value = false
}
}
const handleDeleteRecord = async (id: number) => {
await feedback.confirm('确定删除该记录吗?')
try {
await deleteWechatChatRecord({ id })
wechatRecords.value = wechatRecords.value.filter(r => r.id !== id)
wechatRecordTotal.value--
} catch (e: any) {
feedback.msgError(e?.msg || '删除失败')
}
}
onMounted(async () => { onMounted(async () => {
await getDictOptions() await getDictOptions()
getLists() getLists()
}) })
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped>
.record-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.record-item {
background: #f9fafb;
border-radius: 8px;
padding: 12px;
border: 1px solid #f0f0f0;
}
.record-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.record-content {
font-size: 14px;
line-height: 1.6;
color: #333;
white-space: pre-wrap;
word-break: break-all;
}
</style>
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
@@ -0,0 +1,122 @@
<?php
namespace app\adminapi\controller;
use app\adminapi\controller\BaseAdminController;
use app\adminapi\lists\FanLists;
use app\adminapi\logic\FanLogic;
use app\adminapi\validate\FanValidate;
use app\adminapi\validate\FanVisitRecordValidate;
class FanController extends BaseAdminController
{
/**
* @notes 粉丝列表
*/
public function lists()
{
return $this->dataLists(new FanLists());
}
/**
* @notes 添加粉丝
*/
public function add()
{
$params = (new FanValidate())->post()->goCheck('add');
$params['creator_id'] = $this->adminId;
$params['creator_name'] = $this->adminInfo['name'] ?? '';
$result = FanLogic::add($params);
if ($result) {
return $this->success('添加成功', ['id' => $result], 1, 1);
}
return $this->fail(FanLogic::getError());
}
/**
* @notes 编辑粉丝
*/
public function edit()
{
$params = (new FanValidate())->post()->goCheck('edit');
$result = FanLogic::edit($params);
if ($result) {
return $this->success('编辑成功', [], 1, 1);
}
return $this->fail(FanLogic::getError());
}
/**
* @notes 删除粉丝
*/
public function delete()
{
$params = (new FanValidate())->post()->goCheck('id');
$result = FanLogic::delete($params);
if ($result) {
return $this->success('删除成功', [], 1, 1);
}
return $this->fail(FanLogic::getError());
}
/**
* @notes 粉丝详情
*/
public function detail()
{
$params = (new FanValidate())->goCheck('id');
$result = FanLogic::detail($params);
return $this->data($result);
}
/**
* @notes 回访记录列表
*/
public function visitRecordLists()
{
$params = $this->request->get();
$result = FanLogic::visitRecordLists($params);
return $this->success('', $result);
}
/**
* @notes 添加回访记录
*/
public function addVisitRecord()
{
$params = (new FanVisitRecordValidate())->post()->goCheck('add');
$params['operator_id'] = $this->adminId;
$params['operator_name'] = $this->adminInfo['name'] ?? '';
$result = FanLogic::addVisitRecord($params);
if ($result) {
return $this->success('添加成功', ['id' => $result], 1, 1);
}
return $this->fail(FanLogic::getError());
}
/**
* @notes 编辑回访记录
*/
public function editVisitRecord()
{
$params = (new FanVisitRecordValidate())->post()->goCheck('edit');
$result = FanLogic::editVisitRecord($params);
if ($result) {
return $this->success('编辑成功', [], 1, 1);
}
return $this->fail(FanLogic::getError());
}
/**
* @notes 删除回访记录
*/
public function deleteVisitRecord()
{
$params = (new FanVisitRecordValidate())->post()->goCheck('id');
$result = FanLogic::deleteVisitRecord($params);
if ($result) {
return $this->success('删除成功', [], 1, 1);
}
return $this->fail(FanLogic::getError());
}
}
@@ -18,6 +18,7 @@ use app\adminapi\controller\BaseAdminController;
use app\adminapi\lists\tcm\DiagnosisLists; use app\adminapi\lists\tcm\DiagnosisLists;
use app\adminapi\logic\tcm\DiagnosisLogic; use app\adminapi\logic\tcm\DiagnosisLogic;
use app\adminapi\validate\tcm\DiagnosisValidate; use app\adminapi\validate\tcm\DiagnosisValidate;
use app\common\model\WechatChatRecord;
/** /**
* 中医辨房病因诊单控制器 * 中医辨房病因诊单控制器
@@ -97,6 +98,7 @@ class DiagnosisController extends BaseAdminController
*/ */
public function detail() public function detail()
{ {
$params = (new DiagnosisValidate())->goCheck('id'); $params = (new DiagnosisValidate())->goCheck('id');
$result = DiagnosisLogic::detail($params); $result = DiagnosisLogic::detail($params);
return $this->data($result); return $this->data($result);
@@ -324,6 +326,135 @@ class DiagnosisController extends BaseAdminController
return $this->data($result); return $this->data($result);
} }
/**
* @notes 生成订单小程序码
* @return \think\response\Json
*/
public function generateOrderQrcode()
{
$params = $this->request->post();
$params['share_user_id'] = $this->adminId;
$result = DiagnosisLogic::generateOrderQrcode($params);
if ($result === false) {
return $this->fail(DiagnosisLogic::getError());
}
return $this->data($result);
}
/**
* @notes 获取企业微信聊天记录
*/
public function getWechatChatRecords()
{
$diagnosisId = $this->request->get('diagnosis_id', 0);
$patientId = $this->request->get('patient_id', 0);
$pageNo = $this->request->get('page_no', 1);
$pageSize = $this->request->get('page_size', 20);
if (empty($diagnosisId) && empty($patientId)) {
return $this->fail('诊单ID或患者ID不能都为空');
}
$query = WechatChatRecord::order('chat_time', 'desc');
if ($diagnosisId) {
$query->where('diagnosis_id', $diagnosisId);
}
if ($patientId) {
$query->where('patient_id', $patientId);
}
$count = (clone $query)->count();
$lists = $query->page($pageNo, $pageSize)->select()->toArray();
return $this->data([
'lists' => $lists,
'count' => $count,
'page_no' => $pageNo,
'page_size' => $pageSize
]);
}
/**
* @notes 添加企业微信聊天记录(手动录入/同步写入)
*/
public function addWechatChatRecord()
{
$params = $this->request->post();
if (empty($params['diagnosis_id']) && empty($params['patient_id'])) {
return $this->fail('诊单ID或患者ID不能都为空');
}
if (empty($params['content'])) {
return $this->fail('内容不能为空');
}
$adminInfo = $this->adminInfo;
$data = [
'diagnosis_id' => $params['diagnosis_id'] ?? 0,
'patient_id' => $params['patient_id'] ?? 0,
'staff_userid' => $adminInfo['work_wechat_userid'] ?? ($params['staff_userid'] ?? ''),
'staff_name' => $params['staff_name'] ?? ($adminInfo['name'] ?? ''),
'external_userid' => $params['external_userid'] ?? '',
'external_name' => $params['external_name'] ?? '',
'msg_type' => $params['msg_type'] ?? 'note',
'content' => $params['content'],
'media_url' => $params['media_url'] ?? '',
'chat_time' => $params['chat_time'] ?? time(),
'direction' => $params['direction'] ?? 0,
'create_time' => time(),
];
$record = WechatChatRecord::create($data);
return $this->success('添加成功', ['id' => $record->id]);
}
/**
* @notes 删除企业微信聊天记录
*/
public function deleteWechatChatRecord()
{
$id = $this->request->post('id', 0);
if (empty($id)) {
return $this->fail('记录ID不能为空');
}
WechatChatRecord::destroy($id);
return $this->success('删除成功');
}
/**
* @notes 同步企业微信外部联系人信息(查找该患者在企业微信中的跟进人)
*/
public function getWechatExternalContact()
{
$patientId = $this->request->get('patient_id', 0);
if (empty($patientId)) {
return $this->fail('患者ID不能为空');
}
$result = DiagnosisLogic::getWechatExternalContact($patientId);
if ($result === false) {
return $this->fail(DiagnosisLogic::getError());
}
return $this->data($result);
}
/**
* @notes 获取会话内容存档开启的成员列表
*/
public function getMsgAuditPermitUsers()
{
$result = DiagnosisLogic::getMsgAuditPermitUsers();
if ($result === false) {
return $this->fail(DiagnosisLogic::getError());
}
return $this->data($result);
}
/** /**
* @notes 搜索患者(用于创建订单等场景) * @notes 搜索患者(用于创建订单等场景)
* @return \think\response\Json * @return \think\response\Json
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace app\adminapi\lists;
use app\adminapi\lists\BaseAdminDataLists;
use app\common\model\Fan;
use app\common\model\FanVisitRecord;
use app\common\lists\ListsSearchInterface;
class FanLists extends BaseAdminDataLists implements ListsSearchInterface
{
public function setSearch(): array
{
return [
'%like%' => ['name', 'phone'],
'=' => ['gender', 'status'],
];
}
public function lists(): array
{
$lists = Fan::where($this->searchWhere)
->field(['id', 'name', 'phone', 'id_card', 'age', 'gender', 'remark', 'creator_id', 'creator_name', 'status', 'create_time', 'update_time'])
->append(['gender_desc', 'status_desc'])
->order(['id' => 'desc'])
->limit($this->limitOffset, $this->limitLength)
->select()
->toArray();
$fanIds = array_column($lists, 'id');
if (!empty($fanIds)) {
$visitCounts = FanVisitRecord::where('fan_id', 'in', $fanIds)
->where('delete_time', null)
->group('fan_id')
->column('count(*) as cnt', 'fan_id');
foreach ($lists as &$item) {
$item['visit_count'] = $visitCounts[$item['id']] ?? 0;
}
}
return $lists;
}
public function count(): int
{
return Fan::where($this->searchWhere)->count();
}
}
@@ -60,6 +60,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
} }
$lists = $query $lists = $query
->with(['DiagnosisViewRecord'])
->field(['id', 'patient_id', 'patient_name', 'id_card', 'phone', 'gender', 'age', 'diagnosis_date', 'diagnosis_type', 'syndrome_type', 'assistant_id', 'status', 'create_time', 'update_time']) ->field(['id', 'patient_id', 'patient_name', 'id_card', 'phone', 'gender', 'age', 'diagnosis_date', 'diagnosis_type', 'syndrome_type', 'assistant_id', 'status', 'create_time', 'update_time'])
->append(['gender_desc', 'status_desc', 'diagnosis_date_text']) ->append(['gender_desc', 'status_desc', 'diagnosis_date_text'])
->order(['id' => 'desc']) ->order(['id' => 'desc'])
+244
View File
@@ -0,0 +1,244 @@
<?php
namespace app\adminapi\logic;
use app\common\logic\BaseLogic;
use app\common\model\Fan;
use app\common\model\FanVisitRecord;
use think\facade\Db;
class FanLogic extends BaseLogic
{
/**
* @notes 添加粉丝
* @param array $params
* @return int|bool
*/
public static function add(array $params)
{
try {
if (!empty($params['phone'])) {
$exists = Fan::where('phone', $params['phone'])
->where('delete_time', null)
->find();
if ($exists) {
self::setError('该手机号已存在');
return false;
}
}
if (!empty($params['id_card'])) {
$exists = Fan::where('id_card', $params['id_card'])
->where('delete_time', null)
->find();
if ($exists) {
self::setError('该身份证号已存在');
return false;
}
}
$fan = Fan::create([
'name' => $params['name'],
'phone' => $params['phone'] ?? '',
'id_card' => $params['id_card'] ?? '',
'age' => $params['age'] ?? 0,
'gender' => $params['gender'] ?? 0,
'remark' => $params['remark'] ?? '',
'creator_id' => $params['creator_id'] ?? 0,
'creator_name' => $params['creator_name'] ?? '',
'status' => $params['status'] ?? 1,
]);
return $fan->id;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 编辑粉丝
* @param array $params
* @return bool
*/
public static function edit(array $params)
{
try {
if (!empty($params['phone'])) {
$exists = Fan::where('phone', $params['phone'])
->where('id', '<>', $params['id'])
->where('delete_time', null)
->find();
if ($exists) {
self::setError('该手机号已存在');
return false;
}
}
if (!empty($params['id_card'])) {
$exists = Fan::where('id_card', $params['id_card'])
->where('id', '<>', $params['id'])
->where('delete_time', null)
->find();
if ($exists) {
self::setError('该身份证号已存在');
return false;
}
}
Fan::update([
'id' => $params['id'],
'name' => $params['name'],
'phone' => $params['phone'] ?? '',
'id_card' => $params['id_card'] ?? '',
'age' => $params['age'] ?? 0,
'gender' => $params['gender'] ?? 0,
'remark' => $params['remark'] ?? '',
'status' => $params['status'] ?? 1,
]);
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 删除粉丝
* @param array $params
* @return bool
*/
public static function delete(array $params)
{
try {
Fan::destroy($params['id']);
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 粉丝详情
* @param array $params
* @return array
*/
public static function detail(array $params)
{
$fan = Fan::findOrEmpty($params['id']);
if ($fan->isEmpty()) {
return [];
}
$data = $fan->append(['gender_desc', 'status_desc'])->toArray();
return $data;
}
/**
* @notes 添加回访记录
* @param array $params
* @return int|bool
*/
public static function addVisitRecord(array $params)
{
try {
$fan = Fan::findOrEmpty($params['fan_id']);
if ($fan->isEmpty()) {
self::setError('粉丝不存在');
return false;
}
$record = FanVisitRecord::create([
'fan_id' => $params['fan_id'],
'visit_type' => $params['visit_type'] ?? 1,
'visit_time' => !empty($params['visit_time']) ? strtotime($params['visit_time']) : time(),
'content' => $params['content'] ?? '',
'result' => $params['result'] ?? '',
'next_visit_time' => !empty($params['next_visit_time']) ? strtotime($params['next_visit_time']) : null,
'operator_id' => $params['operator_id'] ?? 0,
'operator_name' => $params['operator_name'] ?? '',
]);
return $record->id;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 编辑回访记录
* @param array $params
* @return bool
*/
public static function editVisitRecord(array $params)
{
try {
FanVisitRecord::update([
'id' => $params['id'],
'visit_type' => $params['visit_type'] ?? 1,
'visit_time' => !empty($params['visit_time']) ? strtotime($params['visit_time']) : time(),
'content' => $params['content'] ?? '',
'result' => $params['result'] ?? '',
'next_visit_time' => !empty($params['next_visit_time']) ? strtotime($params['next_visit_time']) : null,
]);
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 删除回访记录
* @param array $params
* @return bool
*/
public static function deleteVisitRecord(array $params)
{
try {
FanVisitRecord::destroy($params['id']);
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 回访记录列表
* @param array $params
* @return array
*/
public static function visitRecordLists(array $params)
{
$where = [];
if (!empty($params['fan_id'])) {
$where[] = ['fan_id', '=', $params['fan_id']];
}
$pageNo = $params['page_no'] ?? 1;
$pageSize = $params['page_size'] ?? 15;
$count = FanVisitRecord::where($where)->count();
$lists = FanVisitRecord::where($where)
->append(['visit_type_desc'])
->order('id', 'desc')
->page($pageNo, $pageSize)
->select()
->toArray();
foreach ($lists as &$item) {
$item['visit_time_text'] = $item['visit_time'] ? date('Y-m-d H:i', $item['visit_time']) : '';
$item['next_visit_time_text'] = $item['next_visit_time'] ? date('Y-m-d H:i', $item['next_visit_time']) : '';
}
return [
'count' => $count,
'lists' => $lists,
'page_no' => $pageNo,
'page_size' => $pageSize,
];
}
}
+1 -1
View File
@@ -51,7 +51,7 @@ class LoginLogic extends BaseLogic
//设置token //设置token
$adminInfo = AdminTokenService::setToken($admin->id, $params['terminal'], $admin->multipoint_login); $adminInfo = AdminTokenService::setToken($admin->id, $params['terminal'], $admin->multipoint_login);
//返回登录信息 //返回登录信息
$avatar = $admin->avatar ? $admin->avatar : Config::get('project.default_image.admin_avatar'); $avatar = $admin->avatar ? $admin->avatar : Config::get('project.default_image.admin_avatar');
$avatar = FileService::getFileUrl($avatar); $avatar = FileService::getFileUrl($avatar);
@@ -16,7 +16,7 @@ namespace app\adminapi\logic\tcm;
use app\common\logic\BaseLogic; use app\common\logic\BaseLogic;
use app\common\model\tcm\Diagnosis; use app\common\model\tcm\Diagnosis;
use app\common\model\DiagnosisViewRecord;
/** /**
* 中医辨房病因诊单逻辑 * 中医辨房病因诊单逻辑
* Class DiagnosisLogic * Class DiagnosisLogic
@@ -278,7 +278,8 @@ class DiagnosisLogic extends BaseLogic
if (empty($diagnosis['local_hospital_visit_date']) && !empty($diagnosis['diagnosis_date'])) { if (empty($diagnosis['local_hospital_visit_date']) && !empty($diagnosis['diagnosis_date'])) {
$diagnosis['local_hospital_visit_date'] = $diagnosis['diagnosis_date']; $diagnosis['local_hospital_visit_date'] = $diagnosis['diagnosis_date'];
} }
$diagnosis['is_view'] =DiagnosisViewRecord::where(['diagnosis_id'=> $diagnosis['id'], 'user_id' =>$params['user_id']??0])->find() ? 1 : 0;
return $diagnosis; return $diagnosis;
} }
@@ -986,6 +987,41 @@ class DiagnosisLogic extends BaseLogic
} }
} }
/**
* @notes 生成订单小程序码
*/
public static function generateOrderQrcode(array $params)
{
try {
$orderNo = $params['order_no'] ?? '';
if (empty($orderNo)) {
throw new \Exception('订单号不能为空');
}
$config = self::getMiniProgramConfig();
if (!$config) {
throw new \Exception('小程序配置未设置');
}
$page = 'pages/order/order';
$scene = "order_no={$orderNo}";
$qrcodeUrl = self::generateWxQrcode($config, $page, $scene);
if (!$qrcodeUrl) {
throw new \Exception('生成小程序码失败: ' . self::getError());
}
return [
'qrcode_url' => $qrcodeUrl,
'order_no' => $orderNo
];
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/** /**
* @notes 获取小程序配置 * @notes 获取小程序配置
* @return array|null * @return array|null
@@ -1207,19 +1243,19 @@ class DiagnosisLogic extends BaseLogic
$shareUserId = $params['share_user_id'] ?? 0; $shareUserId = $params['share_user_id'] ?? 0;
// 获取诊单详情 // 获取诊单详情
$diagnosis = self::detail(['id' => $diagnosisId]); $diagnosis = self::detail(['id' => $diagnosisId,'user_id' => $userId]);
if (!$diagnosis) { if (!$diagnosis) {
throw new \Exception('诊单不存在'); throw new \Exception('诊单不存在');
} }
// 记录查看行为 // 记录查看行为
self::recordDiagnosisView([ // self::recordDiagnosisView([
'user_id' => $userId, // 'user_id' => $userId,
'diagnosis_id' => $diagnosisId, // 'diagnosis_id' => $diagnosisId,
'patient_id' => $diagnosis['patient_id'] ?? 0, // 'patient_id' => $diagnosis['patient_id'] ?? 0,
'share_user_id' => $shareUserId // 'share_user_id' => $shareUserId
]); // ]);
return $diagnosis; return $diagnosis;
} catch (\Exception $e) { } catch (\Exception $e) {
@@ -1512,4 +1548,179 @@ class DiagnosisLogic extends BaseLogic
return false; return false;
} }
} }
/**
* @notes 获取患者的企微信息(基于会话内容存档接口)
*/
public static function getWechatExternalContact(int $patientId)
{
try {
$diagnosis = \app\common\model\tcm\Diagnosis::where('patient_id', $patientId)
->field(['id', 'patient_name', 'phone', 'external_userid'])
->findOrEmpty();
if ($diagnosis->isEmpty()) {
$diagnosis = \app\common\model\tcm\Diagnosis::where('id', $patientId)
->field(['id', 'patient_name', 'phone', 'external_userid'])
->findOrEmpty();
}
if ($diagnosis->isEmpty()) {
self::setError('未找到患者信息');
return false;
}
$corpId = env('work_wechat.corp_id', '');
$msgauditSecret = env('work_wechat.msgaudit_secret', '');
$result = [
'patient_name' => $diagnosis->patient_name,
'phone' => $diagnosis->phone,
'external_userid' => $diagnosis->external_userid ?? '',
'msgaudit_enabled' => !empty($corpId) && !empty($msgauditSecret),
'permit_users' => [],
'msgaudit_agree' => [],
];
if (empty($corpId) || empty($msgauditSecret)) {
return $result;
}
$accessToken = self::getAccessToken($corpId, $msgauditSecret, 'msgaudit');
if (!$accessToken) {
return $result;
}
// 获取开启会话存档的成员列表
$permitUsers = self::fetchMsgAuditPermitUsers($accessToken);
$result['permit_users'] = $permitUsers;
// 如果有 external_userid,检查同意存档情况
if (!empty($diagnosis->external_userid) && !empty($permitUsers)) {
$agreeInfo = self::checkMsgAuditAgree($accessToken, $permitUsers, $diagnosis->external_userid);
$result['msgaudit_agree'] = $agreeInfo;
}
return $result;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
// ========== 通用 access_token 获取 ==========
private static function getAccessToken(string $corpId, string $secret, string $type = 'app')
{
$cacheKey = "work_wechat_{$type}_token_" . md5($corpId . $secret);
$cached = \think\facade\Cache::get($cacheKey);
if ($cached) return $cached;
$url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpId}&corpsecret={$secret}";
$response = self::wechatHttpGet($url);
if (!$response || ($response['errcode'] ?? -1) != 0) {
\think\facade\Log::error("获取企微access_token失败[{$type}]: " . json_encode($response));
return false;
}
\think\facade\Cache::set($cacheKey, $response['access_token'], $response['expires_in'] - 200);
return $response['access_token'];
}
// ========== 会话内容存档 msgaudit 接口 ==========
/**
* @notes 获取会话内容存档开启成员列表
*/
public static function getMsgAuditPermitUsers()
{
try {
$corpId = env('work_wechat.corp_id', '');
$msgauditSecret = env('work_wechat.msgaudit_secret', '');
if (empty($corpId) || empty($msgauditSecret)) {
self::setError('会话内容存档Secret未配置(MSGAUDIT_SECRET');
return false;
}
$accessToken = self::getAccessToken($corpId, $msgauditSecret, 'msgaudit');
if (!$accessToken) {
self::setError('获取会话内容存档access_token失败');
return false;
}
$ids = self::fetchMsgAuditPermitUsers($accessToken);
return ['ids' => $ids];
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
private static function fetchMsgAuditPermitUsers(string $accessToken): array
{
$url = "https://qyapi.weixin.qq.com/cgi-bin/msgaudit/get_permit_user_list?access_token={$accessToken}";
$response = self::wechatHttpPost($url, '{}');
if (!$response || ($response['errcode'] ?? -1) != 0) {
return [];
}
return $response['ids'] ?? [];
}
/**
* @notes 检查单聊会话同意存档情况
*/
private static function checkMsgAuditAgree(string $accessToken, array $permitUserIds, string $externalUserId)
{
$infoList = [];
foreach ($permitUserIds as $userId) {
$infoList[] = [
'userid' => $userId,
'exteranalopenid' => $externalUserId,
];
}
$url = "https://qyapi.weixin.qq.com/cgi-bin/msgaudit/check_single_agree?access_token={$accessToken}";
$response = self::wechatHttpPost($url, json_encode(['info' => $infoList]));
if (!$response || ($response['errcode'] ?? -1) != 0) {
return [];
}
return $response['agreeinfo'] ?? [];
}
// ========== HTTP 工具方法 ==========
private static function wechatHttpGet(string $url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$result = curl_exec($ch);
curl_close($ch);
return $result ? json_decode($result, true) : null;
}
private static function wechatHttpPost(string $url, string $jsonBody)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$result = curl_exec($ch);
curl_close($ch);
return $result ? json_decode($result, true) : null;
}
} }
@@ -0,0 +1,46 @@
<?php
namespace app\adminapi\validate;
use app\common\validate\BaseValidate;
class FanValidate extends BaseValidate
{
protected $rule = [
'id' => 'require',
'name' => 'require|length:1,50',
'phone' => 'require|mobile',
'id_card' => 'length:15,18',
'age' => 'number|between:0,150',
'gender' => 'in:0,1,2',
'status' => 'in:0,1',
];
protected $message = [
'id.require' => '参数缺失',
'name.require' => '请输入姓名',
'name.length' => '姓名长度须在1-50位字符',
'phone.require' => '请输入手机号',
'phone.mobile' => '手机号格式不正确',
'id_card.length' => '身份证号长度不正确',
'age.number' => '年龄必须为数字',
'age.between' => '年龄范围0-150',
'gender.in' => '性别参数错误',
'status.in' => '状态参数错误',
];
public function sceneAdd()
{
return $this->remove('id', true);
}
public function sceneEdit()
{
return $this->only(['id', 'name', 'phone', 'id_card', 'age', 'gender', 'status']);
}
public function sceneId()
{
return $this->only(['id']);
}
}
@@ -0,0 +1,40 @@
<?php
namespace app\adminapi\validate;
use app\common\validate\BaseValidate;
class FanVisitRecordValidate extends BaseValidate
{
protected $rule = [
'id' => 'require',
'fan_id' => 'require',
'visit_type' => 'require|in:1,2,3,4,5',
'visit_time' => 'require',
'content' => 'require',
];
protected $message = [
'id.require' => '参数缺失',
'fan_id.require' => '请选择粉丝',
'visit_type.require' => '请选择回访类型',
'visit_type.in' => '回访类型参数错误',
'visit_time.require' => '请选择回访时间',
'content.require' => '请输入回访内容',
];
public function sceneAdd()
{
return $this->remove('id', true);
}
public function sceneEdit()
{
return $this->only(['id', 'visit_type', 'visit_time', 'content', 'result', 'next_visit_time']);
}
public function sceneId()
{
return $this->only(['id']);
}
}
@@ -78,6 +78,11 @@ class DiagnosisValidate extends BaseValidate
->append('share_user_id', 'require'); ->append('share_user_id', 'require');
} }
public function sceneGenerateOrderQrcode()
{
return $this->only([]);
}
protected function checkDiagnosis($value) protected function checkDiagnosis($value)
{ {
$diagnosis = Diagnosis::findOrEmpty($value); $diagnosis = Diagnosis::findOrEmpty($value);
@@ -62,6 +62,9 @@ class PayController extends BaseApiController
if (false === $order) { if (false === $order) {
return $this->fail(PaymentLogic::getError(), $params); return $this->fail(PaymentLogic::getError(), $params);
} }
if (empty($order['user_id'])) {
$order['user_id'] = $this->userId;
}
//支付流程 //支付流程
$redirectUrl = $params['redirect'] ?? '/pages/payment/payment'; $redirectUrl = $params['redirect'] ?? '/pages/payment/payment';
$result = PaymentLogic::pay($params['pay_way'], $params['from'], $order, $this->userInfo['terminal'], $redirectUrl); $result = PaymentLogic::pay($params['pay_way'], $params['from'], $order, $this->userInfo['terminal'], $redirectUrl);
+38 -2
View File
@@ -28,7 +28,7 @@ class TcmController extends BaseApiController
* @notes 不需要登录的方法 * @notes 不需要登录的方法
* @var array * @var array
*/ */
public array $notNeedLogin = ['getPatientSignature', 'diagnosisDetail', 'getDict', 'confirmDiagnosis', 'getCardList']; public array $notNeedLogin = ['getPatientSignature', 'diagnosisDetail', 'getDict', 'confirmDiagnosis', 'getCardList', 'getOrderByNo'];
/** /**
* @notes 获取患者签名(供小程序调用) * @notes 获取患者签名(供小程序调用)
@@ -60,7 +60,7 @@ class TcmController extends BaseApiController
{ {
$params = [ $params = [
'id' => $this->request->get('id'), 'id' => $this->request->get('id'),
'user_id' => $this->request->get('user_id', 0), 'user_id' => $this->userId,
'share_user_id' => $this->request->get('share_user_id', 0) 'share_user_id' => $this->request->get('share_user_id', 0)
]; ];
@@ -238,4 +238,40 @@ class TcmController extends BaseApiController
return $this->fail($e->getMessage()); return $this->fail($e->getMessage());
} }
} }
/**
* @notes 根据订单号获取订单详情(供小程序支付页调用)
* @return \think\response\Json
*/
public function getOrderByNo()
{
$orderNo = $this->request->get('order_no', '');
if (empty($orderNo)) {
return $this->fail('订单号不能为空');
}
try {
$order = \app\common\model\Order::where('order_no', $orderNo)->find();
if (!$order) {
return $this->fail('订单不存在');
}
$typeMap = [1 => '挂号费', 2 => '问诊费', 3 => '药品费用'];
$statusMap = [1 => '待支付', 2 => '已支付', 3 => '已取消', 4 => '已退款'];
return $this->data([
'id' => $order['id'],
'order_no' => $order['order_no'],
'order_type' => $order['order_type'],
'order_type_desc' => $typeMap[$order['order_type']] ?? '未知',
'amount' => $order['amount'],
'status' => $order['status'],
'status_desc' => $statusMap[$order['status']] ?? '未知',
'remark' => $order['remark'] ?? '',
'create_time' => $order['create_time'],
]);
} catch (\Exception $e) {
return $this->fail($e->getMessage());
}
}
} }
+1
View File
@@ -98,6 +98,7 @@ class AdminTokenCache extends BaseCache
'terminal' => $adminSession->terminal, 'terminal' => $adminSession->terminal,
'expire_time' => $adminSession->expire_time, 'expire_time' => $adminSession->expire_time,
'login_ip' => request()->ip(), 'login_ip' => request()->ip(),
'work_wechat_userid' => $admin->work_wechat_userid ?? '',
]; ];
$this->set($this->prefix . $token, $adminInfo, new \DateTime(Date('Y-m-d H:i:s', $adminSession->expire_time))); $this->set($this->prefix . $token, $adminInfo, new \DateTime(Date('Y-m-d H:i:s', $adminSession->expire_time)));
return $this->getAdminInfo($token); return $this->getAdminInfo($token);
+19 -1
View File
@@ -84,5 +84,23 @@ class PayNotifyLogic extends BaseLogic
$order->save(); $order->save();
} }
/**
* @notes 订单支付回调
* @param $orderSn
* @param array $extra
*/
public static function order($orderSn, array $extra = [])
{
$order = \app\common\model\Order::where('order_no', $orderSn)->findOrEmpty();
if ($order->isEmpty()) {
throw new \Exception('订单不存在: ' . $orderSn);
}
if ($order->status == 2) {
return;
}
$order->status = 2;
$order->pay_time = date('Y-m-d H:i:s');
$order->transaction_id = $extra['transaction_id'] ?? '';
$order->save();
}
} }
+37 -1
View File
@@ -45,8 +45,14 @@ class PaymentLogic extends BaseLogic
{ {
try { try {
if ($params['from'] == 'recharge') { if ($params['from'] == 'recharge') {
// 充值
$order = RechargeOrder::findOrEmpty($params['order_id'])->toArray(); $order = RechargeOrder::findOrEmpty($params['order_id'])->toArray();
} elseif ($params['from'] == 'order') {
$orderModel = \app\common\model\Order::findOrEmpty($params['order_id']);
if (!$orderModel->isEmpty()) {
$order = $orderModel->toArray();
$order['order_amount'] = $order['amount'];
$order['sn'] = $order['order_no'];
}
} }
if (empty($order)) { if (empty($order)) {
@@ -117,6 +123,21 @@ class PaymentLogic extends BaseLogic
'pay_time' => $payTime, 'pay_time' => $payTime,
]; ];
break; break;
case 'order':
$order = \app\common\model\Order::where(['id' => $params['order_id']])
->findOrEmpty();
$statusMap = [1 => 0, 2 => 1, 3 => 0, 4 => 0];
$order['pay_status'] = $statusMap[$order['status']] ?? 0;
$order['pay_way'] = $order['pay_way'] ?? 0;
$orderInfo = [
'order_id' => $order['id'],
'order_sn' => $order['order_no'],
'order_amount' => $order['amount'],
'pay_way' => PayEnum::getPayDesc($order['pay_way']),
'pay_status' => $order['status'] == 2 ? '已支付' : '未支付',
'pay_time' => $order['pay_time'] ?? '',
];
break;
} }
if (empty($order)) { if (empty($order)) {
@@ -152,6 +173,18 @@ class PaymentLogic extends BaseLogic
throw new \Exception('充值订单不存在'); throw new \Exception('充值订单不存在');
} }
break; break;
case 'order':
$order = \app\common\model\Order::findOrEmpty($params['order_id']);
if ($order->isEmpty()) {
throw new \Exception('订单不存在');
}
if ($order['status'] == 2) {
throw new \Exception('订单已支付');
}
$order['order_amount'] = $order['amount'];
$order['sn'] = $order['order_no'];
$order['pay_status'] = PayEnum::UNPAID;
return $order;
} }
if ($order['pay_status'] == PayEnum::ISPAID) { if ($order['pay_status'] == PayEnum::ISPAID) {
@@ -189,6 +222,9 @@ class PaymentLogic extends BaseLogic
case 'recharge': case 'recharge':
RechargeOrder::update(['pay_way' => $payWay, 'pay_sn' => $paySn], ['id' => $order['id']]); RechargeOrder::update(['pay_way' => $payWay, 'pay_sn' => $paySn], ['id' => $order['id']]);
break; break;
case 'order':
\app\common\model\Order::update(['pay_way' => $payWay], ['id' => $order['id']]);
break;
} }
if ($order['order_amount'] == 0) { if ($order['order_amount'] == 0) {
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace app\common\model;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class Fan extends BaseModel
{
use SoftDelete;
protected $name = 'fan';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $deleteTime = 'delete_time';
protected $dateFormat = false;
public function getGenderDescAttr($value, $data)
{
$gender = [0 => '未知', 1 => '男', 2 => '女'];
return $gender[$data['gender']] ?? '未知';
}
public function getStatusDescAttr($value, $data)
{
$status = [0 => '禁用', 1 => '启用'];
return $status[$data['status']] ?? '未知';
}
public function visitRecords()
{
return $this->hasMany(FanVisitRecord::class, 'fan_id', 'id');
}
}
@@ -0,0 +1,29 @@
<?php
namespace app\common\model;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class FanVisitRecord extends BaseModel
{
use SoftDelete;
protected $name = 'fan_visit_record';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $deleteTime = 'delete_time';
protected $dateFormat = false;
public function getVisitTypeDescAttr($value, $data)
{
$types = [1 => '电话', 2 => '微信', 3 => '短信', 4 => '上门', 5 => '其他'];
return $types[$data['visit_type']] ?? '未知';
}
public function fan()
{
return $this->belongsTo(Fan::class, 'fan_id', 'id');
}
}
@@ -0,0 +1,14 @@
<?php
namespace app\common\model;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class WechatChatRecord extends BaseModel
{
use SoftDelete;
protected $name = 'wechat_chat_record';
protected $deleteTime = 'delete_time';
}
+5 -1
View File
@@ -15,7 +15,7 @@
namespace app\common\model\tcm; namespace app\common\model\tcm;
use app\common\model\BaseModel; use app\common\model\BaseModel;
use app\common\model\DiagnosisViewRecord;
/** /**
* 中医辨房病因诊单模型 * 中医辨房病因诊单模型
* Class Diagnosis * Class Diagnosis
@@ -92,4 +92,8 @@ class Diagnosis extends BaseModel
} }
return null; return null;
} }
public function DiagnosisViewRecord()
{
return $this->hasMany(DiagnosisViewRecord::class, 'diagnosis_id', 'id');
}
} }
@@ -374,14 +374,22 @@ class WeChatPayService extends BasePayService
if ($message['trade_state'] === 'SUCCESS') { if ($message['trade_state'] === 'SUCCESS') {
$extra['transaction_id'] = $message['transaction_id']; $extra['transaction_id'] = $message['transaction_id'];
$attach = $message['attach']; $attach = $message['attach'];
$message['out_trade_no'] = mb_substr($message['out_trade_no'], 0, 18);
switch ($attach) { switch ($attach) {
case 'recharge': case 'recharge':
$order = RechargeOrder::where(['sn' => $message['out_trade_no']])->findOrEmpty(); $outTradeNo = mb_substr($message['out_trade_no'], 0, 18);
$order = RechargeOrder::where(['sn' => $outTradeNo])->findOrEmpty();
if($order->isEmpty() || $order->pay_status == PayEnum::ISPAID) { if($order->isEmpty() || $order->pay_status == PayEnum::ISPAID) {
return true; return true;
} }
PayNotifyLogic::handle('recharge', $message['out_trade_no'], $extra); PayNotifyLogic::handle('recharge', $outTradeNo, $extra);
break;
case 'order':
$outTradeNo = mb_substr($message['out_trade_no'], 0, 23);
$orderModel = \app\common\model\Order::where(['order_no' => $outTradeNo])->findOrEmpty();
if($orderModel->isEmpty() || $orderModel->status == 2) {
return true;
}
PayNotifyLogic::handle('order', $outTradeNo, $extra);
break; break;
} }
} }
Binary file not shown.
@@ -0,0 +1,40 @@
-- 粉丝表
CREATE TABLE IF NOT EXISTS `zyt_fan` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '姓名',
`phone` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
`id_card` varchar(18) NOT NULL DEFAULT '' COMMENT '身份证号码',
`age` tinyint(3) unsigned NOT NULL DEFAULT 0 COMMENT '年龄',
`gender` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '性别: 0=未知 1=男 2=女',
`remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
`creator_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建人ID',
`creator_name` varchar(50) NOT NULL DEFAULT '' COMMENT '创建人名称',
`status` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '状态: 0=禁用 1=启用',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) unsigned DEFAULT NULL COMMENT '修改时间',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_phone` (`phone`),
KEY `idx_id_card` (`id_card`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='粉丝表';
-- 粉丝回访记录表
CREATE TABLE IF NOT EXISTS `zyt_fan_visit_record` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`fan_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '关联粉丝ID',
`visit_type` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '回访类型: 1=电话 2=微信 3=短信 4=上门 5=其他',
`visit_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '回访时间',
`content` text COMMENT '回访内容',
`result` varchar(500) NOT NULL DEFAULT '' COMMENT '回访结果',
`next_visit_time` int(10) unsigned DEFAULT NULL COMMENT '下次回访时间',
`operator_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '操作人ID',
`operator_name` varchar(50) NOT NULL DEFAULT '' COMMENT '操作人名称',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) unsigned DEFAULT NULL COMMENT '修改时间',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_fan_id` (`fan_id`),
KEY `idx_visit_time` (`visit_time`),
KEY `idx_operator_id` (`operator_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='粉丝回访记录表';
@@ -0,0 +1,27 @@
-- 企业微信聊天记录表(关联诊单/患者,记录企业微信沟通内容)
CREATE TABLE IF NOT EXISTS `zyt_wechat_chat_record` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`diagnosis_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '关联诊单ID',
`patient_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '关联患者ID',
`staff_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '企业微信成员UserId',
`staff_name` varchar(64) NOT NULL DEFAULT '' COMMENT '成员名称',
`external_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '客户的企业微信external_userid',
`external_name` varchar(128) NOT NULL DEFAULT '' COMMENT '客户名称',
`msg_type` varchar(20) NOT NULL DEFAULT 'text' COMMENT '消息类型: text/image/file/link/note',
`content` text COMMENT '消息内容/摘要',
`media_url` varchar(500) NOT NULL DEFAULT '' COMMENT '媒体文件URL(图片/文件)',
`chat_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '聊天时间戳',
`direction` tinyint(1) NOT NULL DEFAULT 0 COMMENT '方向: 0=员工发出 1=客户发出',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) unsigned DEFAULT NULL COMMENT '修改时间',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_diagnosis_id` (`diagnosis_id`),
KEY `idx_patient_id` (`patient_id`),
KEY `idx_staff_userid` (`staff_userid`),
KEY `idx_chat_time` (`chat_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业微信聊天记录';
-- 给患者诊单表增加企业微信外部联系人ID(用于自动匹配)
ALTER TABLE `zyt_diagnosis`
ADD COLUMN `external_userid` varchar(64) DEFAULT '' COMMENT '企业微信外部联系人ID' AFTER `assistant_id`;
@@ -1 +1 @@
import r from"./error-C6fCuEcx.js";import{f as p,ak as i,I as m,a as e,aN as s,J as o}from"./@vue/runtime-core-D7eUgySO.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/shared-C75lBtbe.js";import"./@vue/reactivity-maRK_BBd.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./index-DgHUF7DW.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const a="/admin/assets/no_perms-jDxcYpYC.png",n={class:"error404"},T=p({__name:"403",setup(c){return(_,t)=>(i(),m("div",n,[e(r,{code:"403",title:"您的账号权限不足,请联系管理员添加权限!","show-btn":!1},{content:s(()=>[...t[0]||(t[0]=[o("div",{class:"flex justify-center"},[o("img",{class:"w-[150px] h-[150px]",src:a,alt:""})],-1)])]),_:1})]))}});export{T as default}; import r from"./error-EGTHqRU0.js";import{f as p,ak as i,I as m,a as e,aN as s,J as o}from"./@vue/runtime-core-D7eUgySO.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/shared-C75lBtbe.js";import"./@vue/reactivity-maRK_BBd.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./index-B-xN0T_Y.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const a="/admin/assets/no_perms-jDxcYpYC.png",n={class:"error404"},T=p({__name:"403",setup(c){return(_,t)=>(i(),m("div",n,[e(r,{code:"403",title:"您的账号权限不足,请联系管理员添加权限!","show-btn":!1},{content:s(()=>[...t[0]||(t[0]=[o("div",{class:"flex justify-center"},[o("img",{class:"w-[150px] h-[150px]",src:a,alt:""})],-1)])]),_:1})]))}});export{T as default};
@@ -1 +1 @@
import o from"./error-C6fCuEcx.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-D7eUgySO.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/shared-C75lBtbe.js";import"./@vue/reactivity-maRK_BBd.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./index-DgHUF7DW.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const i={class:"error404"},R=r({__name:"404",setup(e){return(a,s)=>(t(),m("div",i,[p(o,{code:"404",title:"哎呀,出错了!您访问的页面不存在…"})]))}});export{R as default}; import o from"./error-EGTHqRU0.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-D7eUgySO.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/shared-C75lBtbe.js";import"./@vue/reactivity-maRK_BBd.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./index-B-xN0T_Y.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const i={class:"error404"},R=r({__name:"404",setup(e){return(a,s)=>(t(),m("div",i,[p(o,{code:"404",title:"哎呀,出错了!您访问的页面不存在…"})]))}});export{R as default};
@@ -1 +1 @@
import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-5IyntBU2.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-Cp_4gpIF.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default}; import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-4Qq2bBPm.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-D0yckGv3.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default};
@@ -1 +1 @@
import{G as h,D as q,C as B,I as F,F as I}from"./element-plus-D-JFNXWu.js";import{_ as D}from"./index-Cp_4gpIF.js";import{f as b}from"./index-DgHUF7DW.js";import{f as G,w,ak as j,G as S,aN as r,J as U,a,O as u,A}from"./@vue/runtime-core-D7eUgySO.js";import{y as n,u as y,r as J}from"./@vue/reactivity-maRK_BBd.js";import{Q as k}from"./@vue/shared-C75lBtbe.js";const M={class:"pr-8"},L=G({__name:"account-adjust",props:{show:{type:Boolean,required:!0},value:{type:[Number,String],required:!0}},emits:["update:show","confirm"],setup(d,{emit:V}){const s=y(),i=d,f=V,o=J({action:1,num:"",remark:""}),m=y(),c=A(()=>Number(i.value)+Number(o.num)*(o.action==1?1:-1)),R={num:[{required:!0,message:"请输入调整的金额"}]},g=e=>{if(e.includes("-"))return b.msgError("请输入正整数");o.num=e},x=async()=>{var e;await((e=s.value)==null?void 0:e.validate()),f("confirm",o)},C=()=>{var e;f("update:show",!1),(e=s.value)==null||e.resetFields()};return w(()=>i.show,e=>{var t,l;e?(t=m.value)==null||t.open():(l=m.value)==null||l.close()}),w(c,e=>{e<0&&(b.msgError("调整后余额需大于0"),o.num="")}),(e,t)=>{const l=q,_=F,E=B,v=I,N=h;return j(),S(D,{ref_key:"popupRef",ref:m,title:"余额调整",width:"500px",onConfirm:x,async:!0,onClose:C},{default:r(()=>[U("div",M,[a(N,{ref_key:"formRef",ref:s,model:n(o),"label-width":"120px",rules:R},{default:r(()=>[a(l,{label:"当前余额"},{default:r(()=>[u("¥ "+k(d.value),1)]),_:1}),a(l,{label:"余额增减",required:"",prop:"action"},{default:r(()=>[a(E,{modelValue:n(o).action,"onUpdate:modelValue":t[0]||(t[0]=p=>n(o).action=p)},{default:r(()=>[a(_,{value:1},{default:r(()=>[...t[2]||(t[2]=[u("增加余额",-1)])]),_:1}),a(_,{value:2},{default:r(()=>[...t[3]||(t[3]=[u("扣减余额",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(l,{label:"调整余额",prop:"num"},{default:r(()=>[a(v,{"model-value":n(o).num,placeholder:"请输入调整的金额",type:"number",onInput:g},null,8,["model-value"])]),_:1}),a(l,{label:"调整后余额"},{default:r(()=>[u(" ¥ "+k(n(c)),1)]),_:1}),a(l,{label:"备注",prop:"remark"},{default:r(()=>[a(v,{modelValue:n(o).remark,"onUpdate:modelValue":t[1]||(t[1]=p=>n(o).remark=p),type:"textarea",rows:4},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])])]),_:1},512)}}});export{L as _}; import{G as h,D as q,C as B,I as F,F as I}from"./element-plus-CW0okzRn.js";import{_ as D}from"./index-D0yckGv3.js";import{f as b}from"./index-B-xN0T_Y.js";import{f as G,w,ak as j,G as S,aN as r,J as U,a,O as u,A}from"./@vue/runtime-core-D7eUgySO.js";import{y as n,u as y,r as J}from"./@vue/reactivity-maRK_BBd.js";import{Q as k}from"./@vue/shared-C75lBtbe.js";const M={class:"pr-8"},L=G({__name:"account-adjust",props:{show:{type:Boolean,required:!0},value:{type:[Number,String],required:!0}},emits:["update:show","confirm"],setup(d,{emit:V}){const s=y(),i=d,f=V,o=J({action:1,num:"",remark:""}),m=y(),c=A(()=>Number(i.value)+Number(o.num)*(o.action==1?1:-1)),R={num:[{required:!0,message:"请输入调整的金额"}]},g=e=>{if(e.includes("-"))return b.msgError("请输入正整数");o.num=e},x=async()=>{var e;await((e=s.value)==null?void 0:e.validate()),f("confirm",o)},C=()=>{var e;f("update:show",!1),(e=s.value)==null||e.resetFields()};return w(()=>i.show,e=>{var t,l;e?(t=m.value)==null||t.open():(l=m.value)==null||l.close()}),w(c,e=>{e<0&&(b.msgError("调整后余额需大于0"),o.num="")}),(e,t)=>{const l=q,_=F,E=B,v=I,N=h;return j(),S(D,{ref_key:"popupRef",ref:m,title:"余额调整",width:"500px",onConfirm:x,async:!0,onClose:C},{default:r(()=>[U("div",M,[a(N,{ref_key:"formRef",ref:s,model:n(o),"label-width":"120px",rules:R},{default:r(()=>[a(l,{label:"当前余额"},{default:r(()=>[u("¥ "+k(d.value),1)]),_:1}),a(l,{label:"余额增减",required:"",prop:"action"},{default:r(()=>[a(E,{modelValue:n(o).action,"onUpdate:modelValue":t[0]||(t[0]=p=>n(o).action=p)},{default:r(()=>[a(_,{value:1},{default:r(()=>[...t[2]||(t[2]=[u("增加余额",-1)])]),_:1}),a(_,{value:2},{default:r(()=>[...t[3]||(t[3]=[u("扣减余额",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(l,{label:"调整余额",prop:"num"},{default:r(()=>[a(v,{"model-value":n(o).num,placeholder:"请输入调整的金额",type:"number",onInput:g},null,8,["model-value"])]),_:1}),a(l,{label:"调整后余额"},{default:r(()=>[u(" ¥ "+k(n(c)),1)]),_:1}),a(l,{label:"备注",prop:"remark"},{default:r(()=>[a(v,{modelValue:n(o).remark,"onUpdate:modelValue":t[1]||(t[1]=p=>n(o).remark=p),type:"textarea",rows:4},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])])]),_:1},512)}}});export{L as _};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as o}from"./add-nav.vue_vue_type_script_setup_true_lang-DzYP1kb2.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default}; import{_ as o}from"./add-nav.vue_vue_type_script_setup_true_lang-D35PNbnR.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default};
@@ -1 +1 @@
import{F as E,D as N,g as B,i as C}from"./element-plus-D-JFNXWu.js";import{_ as $}from"./index-kKVJiUCL.js";import{_ as D}from"./picker-BbSaPsK8.js";import{_ as z}from"./picker-CjRe_gxp.js";import{b as A,f as r}from"./index-DgHUF7DW.js";import{D as I}from"./vuedraggable-DoxySVw6.js";import{f as F,ak as p,I as R,J as l,a,aN as d,G,O as J,A as L}from"./@vue/runtime-core-D7eUgySO.js";import{y as c,a as O}from"./@vue/reactivity-maRK_BBd.js";const P={class:"bg-fill-light flex items-center w-full p-4 mb-4"},S={class:"upload-btn w-[60px] h-[60px]"},T={class:"ml-3 flex-1"},j={class:"flex items-center"},q={class:"flex items-center mt-[18px]"},H={class:"flex-1 flex items-center"},K={class:"drag-move cursor-move ml-auto"},oe=F({__name:"add-nav",props:{modelValue:{type:Array,default:()=>[]},max:{type:Number,default:100},min:{type:Number,default:1}},emits:["update:modelValue"],setup(_,{emit:f}){const t=_,V=f,m=L({get(){return t.modelValue},set(s){V("update:modelValue",s)}}),x=()=>{var s;((s=t.modelValue)==null?void 0:s.length)<t.max?m.value.push({image:"",name:"导航名称",link:{},is_show:"1"}):r.msgError(`最多添加${t.max}`)},g=s=>{var e;if(((e=t.modelValue)==null?void 0:e.length)<=t.min)return r.msgError(`最少保留${t.min}`);m.value.splice(s,1)};return(s,e)=>{const i=A,v=z,h=E,k=D,b=B,w=N,y=$,U=C;return p(),R("div",null,[l("div",null,[a(c(I),{class:"draggable",modelValue:c(m),"onUpdate:modelValue":e[0]||(e[0]=o=>O(m)?m.value=o:null),animation:"300",handle:".drag-move","item-key":"index"},{item:d(({element:o,index:u})=>[(p(),G(y,{class:"w-[467px]",key:u,onClose:n=>g(u)},{default:d(()=>[l("div",P,[a(v,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:d(()=>[l("div",S,[a(i,{name:"el-icon-Plus",size:20})])]),_:1},8,["modelValue","onUpdate:modelValue"]),l("div",T,[l("div",j,[e[1]||(e[1]=l("span",{class:"text-tx-regular flex-none mr-3"},"名称",-1)),a(h,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),l("div",q,[e[2]||(e[2]=l("span",{class:"text-tx-regular flex-none mr-3"},"链接",-1)),a(k,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),a(w,{label:"是否显示",class:"mt-[18px]"},{default:d(()=>[l("div",H,[a(b,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),l("div",K,[a(i,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),l("div",null,[a(U,{type:"primary",onClick:x},{default:d(()=>[...e[3]||(e[3]=[J("添加",-1)])]),_:1})])])}}});export{oe as _}; import{F as E,D as N,g as B,i as C}from"./element-plus-CW0okzRn.js";import{_ as $}from"./index-DuKRmu-Q.js";import{_ as D}from"./picker-Dl86YumP.js";import{_ as z}from"./picker-BTfE-579.js";import{b as A,f as r}from"./index-B-xN0T_Y.js";import{D as I}from"./vuedraggable-DoxySVw6.js";import{f as F,ak as p,I as R,J as l,a,aN as d,G,O as J,A as L}from"./@vue/runtime-core-D7eUgySO.js";import{y as c,a as O}from"./@vue/reactivity-maRK_BBd.js";const P={class:"bg-fill-light flex items-center w-full p-4 mb-4"},S={class:"upload-btn w-[60px] h-[60px]"},T={class:"ml-3 flex-1"},j={class:"flex items-center"},q={class:"flex items-center mt-[18px]"},H={class:"flex-1 flex items-center"},K={class:"drag-move cursor-move ml-auto"},oe=F({__name:"add-nav",props:{modelValue:{type:Array,default:()=>[]},max:{type:Number,default:100},min:{type:Number,default:1}},emits:["update:modelValue"],setup(_,{emit:f}){const t=_,V=f,m=L({get(){return t.modelValue},set(s){V("update:modelValue",s)}}),x=()=>{var s;((s=t.modelValue)==null?void 0:s.length)<t.max?m.value.push({image:"",name:"导航名称",link:{},is_show:"1"}):r.msgError(`最多添加${t.max}`)},g=s=>{var e;if(((e=t.modelValue)==null?void 0:e.length)<=t.min)return r.msgError(`最少保留${t.min}`);m.value.splice(s,1)};return(s,e)=>{const i=A,v=z,h=E,k=D,b=B,w=N,y=$,U=C;return p(),R("div",null,[l("div",null,[a(c(I),{class:"draggable",modelValue:c(m),"onUpdate:modelValue":e[0]||(e[0]=o=>O(m)?m.value=o:null),animation:"300",handle:".drag-move","item-key":"index"},{item:d(({element:o,index:u})=>[(p(),G(y,{class:"w-[467px]",key:u,onClose:n=>g(u)},{default:d(()=>[l("div",P,[a(v,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:d(()=>[l("div",S,[a(i,{name:"el-icon-Plus",size:20})])]),_:1},8,["modelValue","onUpdate:modelValue"]),l("div",T,[l("div",j,[e[1]||(e[1]=l("span",{class:"text-tx-regular flex-none mr-3"},"名称",-1)),a(h,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),l("div",q,[e[2]||(e[2]=l("span",{class:"text-tx-regular flex-none mr-3"},"链接",-1)),a(k,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),a(w,{label:"是否显示",class:"mt-[18px]"},{default:d(()=>[l("div",H,[a(b,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),l("div",K,[a(i,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),l("div",null,[a(U,{type:"primary",onClick:x},{default:d(()=>[...e[3]||(e[3]=[J("添加",-1)])]),_:1})])])}}});export{oe as _};
@@ -1 +1 @@
import{r as n}from"./index-DgHUF7DW.js";function e(t){return n.get({url:"/auth.admin/lists",params:t},{ignoreCancelToken:!0})}function i(t){return n.post({url:"/auth.admin/add",params:t})}function r(t){return n.post({url:"/auth.admin/edit",params:t})}function u(t){return n.post({url:"/auth.admin/delete",params:t})}function d(t){return n.get({url:"/auth.admin/detail",params:t})}export{e as a,r as b,u as c,i as d,d as e}; import{r as n}from"./index-B-xN0T_Y.js";function e(t){return n.get({url:"/auth.admin/lists",params:t},{ignoreCancelToken:!0})}function i(t){return n.post({url:"/auth.admin/add",params:t})}function r(t){return n.post({url:"/auth.admin/edit",params:t})}function u(t){return n.post({url:"/auth.admin/delete",params:t})}function d(t){return n.get({url:"/auth.admin/detail",params:t})}export{e as a,r as b,u as c,i as d,d as e};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{r as e}from"./index-DgHUF7DW.js";function a(t){return e.get({url:"/article.articleCate/lists",params:t})}function l(t){return e.get({url:"/article.articleCate/all",params:t})}function i(t){return e.post({url:"/article.articleCate/add",params:t})}function c(t){return e.post({url:"/article.articleCate/edit",params:t})}function u(t){return e.post({url:"/article.articleCate/delete",params:t})}function n(t){return e.get({url:"/article.articleCate/detail",params:t})}function s(t){return e.post({url:"/article.articleCate/updateStatus",params:t})}function o(t){return e.get({url:"/article.article/lists",params:t})}function d(t){return e.post({url:"/article.article/add",params:t})}function f(t){return e.post({url:"/article.article/edit",params:t})}function C(t){return e.post({url:"/article.article/delete",params:t})}function p(t){return e.get({url:"/article.article/detail",params:t})}function g(t){return e.post({url:"/article.article/updateStatus",params:t})}export{a,u as b,s as c,c as d,i as e,n as f,p as g,f as h,d as i,l as j,o as k,g as l,C as m}; import{r as e}from"./index-B-xN0T_Y.js";function a(t){return e.get({url:"/article.articleCate/lists",params:t})}function l(t){return e.get({url:"/article.articleCate/all",params:t})}function i(t){return e.post({url:"/article.articleCate/add",params:t})}function c(t){return e.post({url:"/article.articleCate/edit",params:t})}function u(t){return e.post({url:"/article.articleCate/delete",params:t})}function n(t){return e.get({url:"/article.articleCate/detail",params:t})}function s(t){return e.post({url:"/article.articleCate/updateStatus",params:t})}function o(t){return e.get({url:"/article.article/lists",params:t})}function d(t){return e.post({url:"/article.article/add",params:t})}function f(t){return e.post({url:"/article.article/edit",params:t})}function C(t){return e.post({url:"/article.article/delete",params:t})}function p(t){return e.get({url:"/article.article/detail",params:t})}function g(t){return e.post({url:"/article.article/updateStatus",params:t})}export{a,u as b,s as c,c as d,i as e,n as f,p as g,f as h,d as i,l as j,o as k,g as l,C as m};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-BVeCPR9U.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./picker-CjRe_gxp.js";import"./index-Cp_4gpIF.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./index-BatBRS96.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./index-kKVJiUCL.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./usePaging-CPrBIeJ2.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-CLOIDZlW.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./picker-BTfE-579.js";import"./index-D0yckGv3.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./index-BZIFSND_.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./index-DuKRmu-Q.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./usePaging-CPrBIeJ2.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-C0vw4jHc.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";import"./index.vue_vue_type_script_setup_true_lang-DLBTczRQ.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-jswPq3cr.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";import"./index.vue_vue_type_script_setup_true_lang-CeIOHMQu.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Dolm4gBY.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-DzYP1kb2.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DbgUSOxW.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-D35PNbnR.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-BWsj4xT0.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-DzYP1kb2.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-CwUA_Y5J.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-D35PNbnR.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-B333IY2f.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index.vue_vue_type_script_setup_true_lang-DLBTczRQ.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./picker-CjRe_gxp.js";import"./index-Cp_4gpIF.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./index-BatBRS96.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./index-kKVJiUCL.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./usePaging-CPrBIeJ2.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Bza2DzTj.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index.vue_vue_type_script_setup_true_lang-CeIOHMQu.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./picker-BTfE-579.js";import"./index-D0yckGv3.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./index-BZIFSND_.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./index-DuKRmu-Q.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./usePaging-CPrBIeJ2.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-D1nC6xcc.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-CAm4mxn5.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{m as b,l as c,G as V}from"./element-plus-D-JFNXWu.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-Bj-gOAi3.js";import{f as v,ak as x,I as k,J as E,a as o,aN as e,F as g,A as w}from"./@vue/runtime-core-D7eUgySO.js";import{y as r}from"./@vue/reactivity-maRK_BBd.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";const Et=v({__name:"attr",props:{modelValue:{type:Object,default:()=>({nav:[],menu:{}})}},emits:["update:modelValue"],setup(n,{emit:s}){const u=n,d=s,m=w({get(){return u.modelValue},set(a){d("update:modelValue",a)}});return(a,t)=>{const i=c,f=b,_=V;return x(),k(g,null,[t[2]||(t[2]=E("div",{class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"}," pc导航设置 ",-1)),o(_,{class:"mt-4","label-width":"70px"},{default:e(()=>[o(f,{"model-value":"nav"},{default:e(()=>[o(i,{label:"主导航设置",name:"nav"},{default:e(()=>[o(l,{modelValue:r(m).nav,"onUpdate:modelValue":t[0]||(t[0]=p=>r(m).nav=p)},null,8,["modelValue"])]),_:1}),o(i,{label:"菜单设置",name:"menu"},{default:e(()=>[o(l,{modelValue:r(m).menu,"onUpdate:modelValue":t[1]||(t[1]=p=>r(m).menu=p)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})],64)}}});export{Et as default}; import{m as b,l as c,G as V}from"./element-plus-CW0okzRn.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-CQJwflJ3.js";import{f as v,ak as x,I as k,J as E,a as o,aN as e,F as g,A as w}from"./@vue/runtime-core-D7eUgySO.js";import{y as r}from"./@vue/reactivity-maRK_BBd.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";const Et=v({__name:"attr",props:{modelValue:{type:Object,default:()=>({nav:[],menu:{}})}},emits:["update:modelValue"],setup(n,{emit:s}){const u=n,d=s,m=w({get(){return u.modelValue},set(a){d("update:modelValue",a)}});return(a,t)=>{const i=c,f=b,_=V;return x(),k(g,null,[t[2]||(t[2]=E("div",{class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"}," pc导航设置 ",-1)),o(_,{class:"mt-4","label-width":"70px"},{default:e(()=>[o(f,{"model-value":"nav"},{default:e(()=>[o(i,{label:"主导航设置",name:"nav"},{default:e(()=>[o(l,{modelValue:r(m).nav,"onUpdate:modelValue":t[0]||(t[0]=p=>r(m).nav=p)},null,8,["modelValue"])]),_:1}),o(i,{label:"菜单设置",name:"menu"},{default:e(()=>[o(l,{modelValue:r(m).menu,"onUpdate:modelValue":t[1]||(t[1]=p=>r(m).menu=p)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})],64)}}});export{Et as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-CbZc-emu.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-mCYFDcgx.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default};
@@ -1 +0,0 @@
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-B8zizKA0.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-CJm63QHA.js";import"./attr-Djnfw8Qd.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";import"./content.vue_vue_type_script_setup_true_lang-BX_s3_sc.js";import"./decoration-img-CttNGVCW.js";import"./attr.vue_vue_type_script_setup_true_lang-BVeCPR9U.js";import"./content-BlSCSVcA.js";import"./attr.vue_vue_type_script_setup_true_lang-D1nC6xcc.js";import"./content.vue_vue_type_script_setup_true_lang-B5-3GwBf.js";import"./attr.vue_vue_type_script_setup_true_lang-BWsj4xT0.js";import"./add-nav.vue_vue_type_script_setup_true_lang-DzYP1kb2.js";import"./content-BmSHWdWq.js";import"./attr.vue_vue_type_script_setup_true_lang-Dolm4gBY.js";import"./content.vue_vue_type_script_setup_true_lang-B2hMMnZ0.js";import"./attr.vue_vue_type_script_setup_true_lang-DmW31KP_.js";import"./content-BEOEfESW.js";import"./decoration-CfOm5lOP.js";import"./attr.vue_vue_type_script_setup_true_lang-B333IY2f.js";import"./index.vue_vue_type_script_setup_true_lang-DLBTczRQ.js";import"./content-BcVo33hb.js";import"./content.vue_vue_type_script_setup_true_lang-CyJb5BW9.js";import"./attr.vue_vue_type_script_setup_true_lang-BU9HfYpn.js";import"./content-CkPP-n42.js";import"./attr.vue_vue_type_script_setup_true_lang-CbZc-emu.js";import"./content.vue_vue_type_script_setup_true_lang-FaipDzzu.js";import"./attr.vue_vue_type_script_setup_true_lang-B-j5hhf5.js";import"./content-DjoACUXH.js";export{o as default};
@@ -0,0 +1 @@
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-EvElmjFj.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-4mQRuxrN.js";import"./attr-DQ6i966I.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";import"./content.vue_vue_type_script_setup_true_lang-mR0br7S_.js";import"./decoration-img-CC8K0JZ3.js";import"./attr.vue_vue_type_script_setup_true_lang-CLOIDZlW.js";import"./content-CpefMLLM.js";import"./attr.vue_vue_type_script_setup_true_lang-CAm4mxn5.js";import"./content.vue_vue_type_script_setup_true_lang-DRsiE0N3.js";import"./attr.vue_vue_type_script_setup_true_lang-CwUA_Y5J.js";import"./add-nav.vue_vue_type_script_setup_true_lang-D35PNbnR.js";import"./content-HLmrri-x.js";import"./attr.vue_vue_type_script_setup_true_lang-DbgUSOxW.js";import"./content.vue_vue_type_script_setup_true_lang-Cw2r_EPh.js";import"./attr.vue_vue_type_script_setup_true_lang-DmW31KP_.js";import"./content-DdEC1Oct.js";import"./decoration-DcrKh-Qh.js";import"./attr.vue_vue_type_script_setup_true_lang-Bza2DzTj.js";import"./index.vue_vue_type_script_setup_true_lang-CeIOHMQu.js";import"./content-BkupS7cM.js";import"./content.vue_vue_type_script_setup_true_lang-BELbd7NG.js";import"./attr.vue_vue_type_script_setup_true_lang-BU9HfYpn.js";import"./content-Ps87ex5t.js";import"./attr.vue_vue_type_script_setup_true_lang-mCYFDcgx.js";import"./content.vue_vue_type_script_setup_true_lang-Lx1f1O3E.js";import"./attr.vue_vue_type_script_setup_true_lang-B-j5hhf5.js";import"./content-DdjngYyE.js";export{o as default};
@@ -1 +1 @@
import{J as y,s as g}from"./element-plus-D-JFNXWu.js";import{e as b}from"./index-CJm63QHA.js";import{f as x,ak as o,I as _,a as r,aN as c,J as h,G as i,K as w,at as k}from"./@vue/runtime-core-D7eUgySO.js";import{Q as v}from"./@vue/shared-C75lBtbe.js";import{y as C}from"./@vue/reactivity-maRK_BBd.js";const B={class:"pages-setting"},E={class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2 text-xl font-medium"},V=x({__name:"attr-setting",props:{widget:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(e,{emit:m}){const d=m,p=a=>{d("update:content",a)};return(a,N)=>{const f=y,u=g;return o(),_("div",B,[r(f,{shadow:"never",class:"!border-none flex"},{default:c(()=>{var t;return[h("div",E,v((t=e.widget)==null?void 0:t.title),1)]}),_:1}),r(u,{class:"w-full",style:{height:"calc(100% - 60px)"}},{default:c(()=>{var t,n,s,l;return[(o(),i(w,null,[(o(),i(k((n=C(b)[(t=e.widget)==null?void 0:t.name])==null?void 0:n.attr),{content:(s=e.widget)==null?void 0:s.content,styles:(l=e.widget)==null?void 0:l.styles,type:e.type,"onUpdate:content":p},null,40,["content","styles","type"]))],1024))]}),_:1})])}}});export{V as _}; import{J as y,s as g}from"./element-plus-CW0okzRn.js";import{e as b}from"./index-4mQRuxrN.js";import{f as x,ak as o,I as _,a as r,aN as c,J as h,G as i,K as w,at as k}from"./@vue/runtime-core-D7eUgySO.js";import{Q as v}from"./@vue/shared-C75lBtbe.js";import{y as C}from"./@vue/reactivity-maRK_BBd.js";const B={class:"pages-setting"},E={class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2 text-xl font-medium"},V=x({__name:"attr-setting",props:{widget:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(e,{emit:m}){const d=m,p=a=>{d("update:content",a)};return(a,N)=>{const f=y,u=g;return o(),_("div",B,[r(f,{shadow:"never",class:"!border-none flex"},{default:c(()=>{var t;return[h("div",E,v((t=e.widget)==null?void 0:t.title),1)]}),_:1}),r(u,{class:"w-full",style:{height:"calc(100% - 60px)"}},{default:c(()=>{var t,n,s,l;return[(o(),i(w,null,[(o(),i(k((n=C(b)[(t=e.widget)==null?void 0:t.name])==null?void 0:n.attr),{content:(s=e.widget)==null?void 0:s.content,styles:(l=e.widget)==null?void 0:l.styles,type:e.type,"onUpdate:content":p},null,40,["content","styles","type"]))],1024))]}),_:1})])}}});export{V as _};
@@ -1 +1 @@
import{J as E,D as F,C,I as N,F as z,G as B}from"./element-plus-D-JFNXWu.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-DLBTczRQ.js";import{_ as I}from"./picker-CjRe_gxp.js";import{f as O,ak as r,G as s,aN as t,a as l,O as p,H as i,J as y,A as j}from"./@vue/runtime-core-D7eUgySO.js";import{y as a}from"./@vue/reactivity-maRK_BBd.js";const T=O({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(m,{emit:g}){const b=g,x=m,o=j({get:()=>x.content,set:_=>{b("update:content",_)}});return(_,e)=>{const u=N,f=C,d=F,k=z,V=I,v=G,U=E,w=B;return r(),s(w,{ref:"form","label-width":"80px",size:"large"},{default:t(()=>[l(U,{shadow:"never",class:"!border-none flex mt-2"},{default:t(()=>[l(d,{label:"页面标题"},{default:t(()=>[l(f,{modelValue:a(o).title_type,"onUpdate:modelValue":e[0]||(e[0]=n=>a(o).title_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[7]||(e[7]=[p("文字",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[8]||(e[8]=[p("图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.title_type==1?(r(),s(d,{key:0},{default:t(()=>[l(k,{modelValue:a(o).title,"onUpdate:modelValue":e[1]||(e[1]=n=>a(o).title=n),maxlength:"8","show-word-limit":"",class:"w-[300px]",placeholder:"请输入页面标题"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.title_type==2?(r(),s(d,{key:1},{default:t(()=>[l(V,{modelValue:a(o).title_img,"onUpdate:modelValue":e[2]||(e[2]=n=>a(o).title_img=n),limit:1,size:"100px"},null,8,["modelValue"]),e[9]||(e[9]=y("div",{class:"form-tips"},"建议图片尺寸:300px*40px",-1))]),_:1})):i("",!0),m.content.title_type==1?(r(),s(d,{key:2,label:"文字颜色"},{default:t(()=>[l(f,{modelValue:a(o).text_color,"onUpdate:modelValue":e[3]||(e[3]=n=>a(o).text_color=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[10]||(e[10]=[p("白色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[11]||(e[11]=[p("黑色",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1})):i("",!0),l(d,{label:"页面背景"},{default:t(()=>[l(f,{modelValue:a(o).bg_type,"onUpdate:modelValue":e[4]||(e[4]=n=>a(o).bg_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[12]||(e[12]=[p("背景颜色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[13]||(e[13]=[p("背景图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.bg_type==1?(r(),s(d,{key:3},{default:t(()=>[l(v,{modelValue:a(o).bg_color,"onUpdate:modelValue":e[5]||(e[5]=n=>a(o).bg_color=n),"reset-color":"#F5F5F5"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.bg_type==2?(r(),s(d,{key:4},{default:t(()=>[l(V,{modelValue:a(o).bg_image,"onUpdate:modelValue":e[6]||(e[6]=n=>a(o).bg_image=n),limit:1,size:"100px"},null,8,["modelValue"]),e[14]||(e[14]=y("div",{class:"form-tips"},"建议图片尺寸:750px*高度不限",-1))]),_:1})):i("",!0)]),_:1})]),_:1},512)}}});export{T as _}; import{J as E,D as F,C,I as N,F as z,G as B}from"./element-plus-CW0okzRn.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-CeIOHMQu.js";import{_ as I}from"./picker-BTfE-579.js";import{f as O,ak as r,G as s,aN as t,a as l,O as p,H as i,J as y,A as j}from"./@vue/runtime-core-D7eUgySO.js";import{y as a}from"./@vue/reactivity-maRK_BBd.js";const T=O({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(m,{emit:g}){const b=g,x=m,o=j({get:()=>x.content,set:_=>{b("update:content",_)}});return(_,e)=>{const u=N,f=C,d=F,k=z,V=I,v=G,U=E,w=B;return r(),s(w,{ref:"form","label-width":"80px",size:"large"},{default:t(()=>[l(U,{shadow:"never",class:"!border-none flex mt-2"},{default:t(()=>[l(d,{label:"页面标题"},{default:t(()=>[l(f,{modelValue:a(o).title_type,"onUpdate:modelValue":e[0]||(e[0]=n=>a(o).title_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[7]||(e[7]=[p("文字",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[8]||(e[8]=[p("图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.title_type==1?(r(),s(d,{key:0},{default:t(()=>[l(k,{modelValue:a(o).title,"onUpdate:modelValue":e[1]||(e[1]=n=>a(o).title=n),maxlength:"8","show-word-limit":"",class:"w-[300px]",placeholder:"请输入页面标题"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.title_type==2?(r(),s(d,{key:1},{default:t(()=>[l(V,{modelValue:a(o).title_img,"onUpdate:modelValue":e[2]||(e[2]=n=>a(o).title_img=n),limit:1,size:"100px"},null,8,["modelValue"]),e[9]||(e[9]=y("div",{class:"form-tips"},"建议图片尺寸:300px*40px",-1))]),_:1})):i("",!0),m.content.title_type==1?(r(),s(d,{key:2,label:"文字颜色"},{default:t(()=>[l(f,{modelValue:a(o).text_color,"onUpdate:modelValue":e[3]||(e[3]=n=>a(o).text_color=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[10]||(e[10]=[p("白色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[11]||(e[11]=[p("黑色",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1})):i("",!0),l(d,{label:"页面背景"},{default:t(()=>[l(f,{modelValue:a(o).bg_type,"onUpdate:modelValue":e[4]||(e[4]=n=>a(o).bg_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[12]||(e[12]=[p("背景颜色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[13]||(e[13]=[p("背景图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.bg_type==1?(r(),s(d,{key:3},{default:t(()=>[l(v,{modelValue:a(o).bg_color,"onUpdate:modelValue":e[5]||(e[5]=n=>a(o).bg_color=n),"reset-color":"#F5F5F5"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.bg_type==2?(r(),s(d,{key:4},{default:t(()=>[l(V,{modelValue:a(o).bg_image,"onUpdate:modelValue":e[6]||(e[6]=n=>a(o).bg_image=n),limit:1,size:"100px"},null,8,["modelValue"]),e[14]||(e[14]=y("div",{class:"form-tips"},"建议图片尺寸:750px*高度不限",-1))]),_:1})):i("",!0)]),_:1})]),_:1},512)}}});export{T as _};
@@ -1 +1 @@
import{J as O,D as j,F as A,g as G,i as J,G as S}from"./element-plus-D-JFNXWu.js";import{_ as z}from"./index-kKVJiUCL.js";import{b as H,f as k}from"./index-DgHUF7DW.js";import{_ as R}from"./picker-BbSaPsK8.js";import{_ as T}from"./picker-CjRe_gxp.js";import{D as q}from"./vuedraggable-DoxySVw6.js";import{l as v}from"./lodash-es-BADexyn7.js";import{f as K,ak as c,I as b,a as o,aN as s,J as n,G as u,H as r,O as L,A as M}from"./@vue/runtime-core-D7eUgySO.js";import{y as _}from"./@vue/reactivity-maRK_BBd.js";const P={class:"flex-1"},Q={class:"bg-fill-light w-full p-4 mt-4"},W={class:"flex-1"},X={class:"flex-1 flex items-center"},Y={class:"drag-move cursor-move ml-auto"},Z={key:0,class:"mt-4"},f=5,me=K({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(m,{emit:y}){const p=y,d=m,g=M({get:()=>d.content,set:a=>{p("update:content",a)}}),w=()=>{var a;if(((a=d.content.data)==null?void 0:a.length)<f){const e=v(d.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),p("update:content",e)}else k.msgError(`最多添加${f}张图片`)},E=a=>{var i;if(((i=d.content.data)==null?void 0:i.length)<=1)return k.msgError("最少保留一张图片");const e=v(d.content);e.data.splice(a,1),p("update:content",e)};return(a,e)=>{const i=T,U=R,C=A,h=j,D=G,B=H,N=z,$=J,F=O,I=S;return c(),b("div",null,[o(I,{"label-width":"70px"},{default:s(()=>[o(F,{shadow:"never",class:"!border-none flex mt-2"},{default:s(()=>{var x;return[e[2]||(e[2]=n("div",{class:"flex items-end"},[n("div",{class:"text-base text-[#101010] font-medium"},"图片设置"),n("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),n("div",P,[o(_(q),{class:"draggable",modelValue:_(g).data,"onUpdate:modelValue":e[0]||(e[0]=t=>_(g).data=t),animation:"300",handle:".drag-move"},{item:s(({element:t,index:V})=>[(c(),u(N,{key:V,onClose:l=>E(V),class:"w-full"},{default:s(()=>[n("div",Q,[o(i,{width:"396px",height:"196px",modelValue:t.image,"onUpdate:modelValue":l=>t.image=l,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),n("div",W,[o(h,{class:"mt-[18px]",label:"图片链接"},{default:s(()=>[m.type=="mobile"?(c(),u(U,{key:0,modelValue:t.link,"onUpdate:modelValue":l=>t.link=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0),m.type=="pc"?(c(),u(C,{key:1,placeholder:"请输入链接",modelValue:t.link.path,"onUpdate:modelValue":l=>t.link.path=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0)]),_:2},1024),o(h,{label:"是否显示",class:"mt-[18px] !mb-0"},{default:s(()=>[n("div",X,[o(D,{modelValue:t.is_show,"onUpdate:modelValue":l=>t.is_show=l,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),n("div",Y,[o(B,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),((x=m.content.data)==null?void 0:x.length)<f?(c(),b("div",Z,[o($,{class:"w-full",type:"primary",onClick:w},{default:s(()=>[...e[1]||(e[1]=[L("添加图片",-1)])]),_:1})])):r("",!0)]}),_:1})]),_:1})])}}});export{me as _}; import{J as O,D as j,F as A,g as G,i as J,G as S}from"./element-plus-CW0okzRn.js";import{_ as z}from"./index-DuKRmu-Q.js";import{b as H,f as k}from"./index-B-xN0T_Y.js";import{_ as R}from"./picker-Dl86YumP.js";import{_ as T}from"./picker-BTfE-579.js";import{D as q}from"./vuedraggable-DoxySVw6.js";import{l as v}from"./lodash-es-BADexyn7.js";import{f as K,ak as c,I as b,a as o,aN as s,J as n,G as u,H as r,O as L,A as M}from"./@vue/runtime-core-D7eUgySO.js";import{y as _}from"./@vue/reactivity-maRK_BBd.js";const P={class:"flex-1"},Q={class:"bg-fill-light w-full p-4 mt-4"},W={class:"flex-1"},X={class:"flex-1 flex items-center"},Y={class:"drag-move cursor-move ml-auto"},Z={key:0,class:"mt-4"},f=5,me=K({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(m,{emit:y}){const p=y,d=m,g=M({get:()=>d.content,set:a=>{p("update:content",a)}}),w=()=>{var a;if(((a=d.content.data)==null?void 0:a.length)<f){const e=v(d.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),p("update:content",e)}else k.msgError(`最多添加${f}张图片`)},E=a=>{var i;if(((i=d.content.data)==null?void 0:i.length)<=1)return k.msgError("最少保留一张图片");const e=v(d.content);e.data.splice(a,1),p("update:content",e)};return(a,e)=>{const i=T,U=R,C=A,h=j,D=G,B=H,N=z,$=J,F=O,I=S;return c(),b("div",null,[o(I,{"label-width":"70px"},{default:s(()=>[o(F,{shadow:"never",class:"!border-none flex mt-2"},{default:s(()=>{var x;return[e[2]||(e[2]=n("div",{class:"flex items-end"},[n("div",{class:"text-base text-[#101010] font-medium"},"图片设置"),n("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),n("div",P,[o(_(q),{class:"draggable",modelValue:_(g).data,"onUpdate:modelValue":e[0]||(e[0]=t=>_(g).data=t),animation:"300",handle:".drag-move"},{item:s(({element:t,index:V})=>[(c(),u(N,{key:V,onClose:l=>E(V),class:"w-full"},{default:s(()=>[n("div",Q,[o(i,{width:"396px",height:"196px",modelValue:t.image,"onUpdate:modelValue":l=>t.image=l,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),n("div",W,[o(h,{class:"mt-[18px]",label:"图片链接"},{default:s(()=>[m.type=="mobile"?(c(),u(U,{key:0,modelValue:t.link,"onUpdate:modelValue":l=>t.link=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0),m.type=="pc"?(c(),u(C,{key:1,placeholder:"请输入链接",modelValue:t.link.path,"onUpdate:modelValue":l=>t.link.path=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0)]),_:2},1024),o(h,{label:"是否显示",class:"mt-[18px] !mb-0"},{default:s(()=>[n("div",X,[o(D,{modelValue:t.is_show,"onUpdate:modelValue":l=>t.is_show=l,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),n("div",Y,[o(B,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),((x=m.content.data)==null?void 0:x.length)<f?(c(),b("div",Z,[o($,{class:"w-full",type:"primary",onClick:w},{default:s(()=>[...e[1]||(e[1]=[L("添加图片",-1)])]),_:1})])):r("",!0)]}),_:1})]),_:1})])}}});export{me as _};
@@ -1 +1 @@
import{J as V,D as w,F as x,G as b}from"./element-plus-D-JFNXWu.js";import{_ as g}from"./picker-CjRe_gxp.js";import{f as k,ak as E,I as U,a as e,aN as n,J as y,A as v}from"./@vue/runtime-core-D7eUgySO.js";import{y as o}from"./@vue/reactivity-maRK_BBd.js";const N=k({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:r}){const p=r,i=u,l=v({get:()=>i.content,set:d=>{p("update:content",d)}});return(d,t)=>{const s=x,m=w,_=g,c=V,f=b;return E(),U("div",null,[e(f,{"label-width":"90px",size:"large","label-position":"top"},{default:n(()=>[e(c,{shadow:"never",class:"!border-none flex mt-2"},{default:n(()=>[e(m,{label:"平台名称"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).title,"onUpdate:modelValue":t[0]||(t[0]=a=>o(l).title=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"客服二维码"},{default:n(()=>[y("div",null,[e(_,{modelValue:o(l).qrcode,"onUpdate:modelValue":t[1]||(t[1]=a=>o(l).qrcode=a),"exclude-domain":""},null,8,["modelValue"])])]),_:1}),e(m,{label:"备注"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).remark,"onUpdate:modelValue":t[2]||(t[2]=a=>o(l).remark=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"联系电话"},{default:n(()=>[e(s,{class:"w-[400px]",modelValue:o(l).mobile,"onUpdate:modelValue":t[3]||(t[3]=a=>o(l).mobile=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"服务时间"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).time,"onUpdate:modelValue":t[4]||(t[4]=a=>o(l).time=a)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})])}}});export{N as _}; import{J as V,D as w,F as x,G as b}from"./element-plus-CW0okzRn.js";import{_ as g}from"./picker-BTfE-579.js";import{f as k,ak as E,I as U,a as e,aN as n,J as y,A as v}from"./@vue/runtime-core-D7eUgySO.js";import{y as o}from"./@vue/reactivity-maRK_BBd.js";const N=k({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:r}){const p=r,i=u,l=v({get:()=>i.content,set:d=>{p("update:content",d)}});return(d,t)=>{const s=x,m=w,_=g,c=V,f=b;return E(),U("div",null,[e(f,{"label-width":"90px",size:"large","label-position":"top"},{default:n(()=>[e(c,{shadow:"never",class:"!border-none flex mt-2"},{default:n(()=>[e(m,{label:"平台名称"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).title,"onUpdate:modelValue":t[0]||(t[0]=a=>o(l).title=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"客服二维码"},{default:n(()=>[y("div",null,[e(_,{modelValue:o(l).qrcode,"onUpdate:modelValue":t[1]||(t[1]=a=>o(l).qrcode=a),"exclude-domain":""},null,8,["modelValue"])])]),_:1}),e(m,{label:"备注"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).remark,"onUpdate:modelValue":t[2]||(t[2]=a=>o(l).remark=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"联系电话"},{default:n(()=>[e(s,{class:"w-[400px]",modelValue:o(l).mobile,"onUpdate:modelValue":t[3]||(t[3]=a=>o(l).mobile=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"服务时间"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).time,"onUpdate:modelValue":t[4]||(t[4]=a=>o(l).time=a)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})])}}});export{N as _};
@@ -1 +1 @@
import{J as b,D as y,F as E,C as w,I as C,G as I}from"./element-plus-D-JFNXWu.js";import{_ as N}from"./add-nav.vue_vue_type_script_setup_true_lang-DzYP1kb2.js";import{f as k,ak as B,I as F,a as t,aN as o,J as a,O as u,A as O}from"./@vue/runtime-core-D7eUgySO.js";import{y as s}from"./@vue/reactivity-maRK_BBd.js";const U={class:"flex-1"},J=k({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(p,{emit:i}){const f=i,_=p,l=O({get:()=>_.content,set:m=>{f("update:content",m)}});return(m,e)=>{const x=E,c=y,d=b,r=C,v=w,V=I;return B(),F("div",null,[t(V,{"label-width":"70px"},{default:o(()=>[t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[t(c,{label:"标题"},{default:o(()=>[t(x,{class:"w-[396px]",modelValue:s(l).title,"onUpdate:modelValue":e[0]||(e[0]=n=>s(l).title=n)},null,8,["modelValue"])]),_:1})]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[5]||(e[5]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),t(v,{modelValue:s(l).style,"onUpdate:modelValue":e[1]||(e[1]=n=>s(l).style=n)},{default:o(()=>[t(r,{value:1},{default:o(()=>[...e[3]||(e[3]=[u("横排",-1)])]),_:1}),t(r,{value:2},{default:o(()=>[...e[4]||(e[4]=[u("竖排",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"菜单"),a("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),a("div",U,[t(N,{modelValue:s(l).data,"onUpdate:modelValue":e[2]||(e[2]=n=>s(l).data=n)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{J as _}; import{J as b,D as y,F as E,C as w,I as C,G as I}from"./element-plus-CW0okzRn.js";import{_ as N}from"./add-nav.vue_vue_type_script_setup_true_lang-D35PNbnR.js";import{f as k,ak as B,I as F,a as t,aN as o,J as a,O as u,A as O}from"./@vue/runtime-core-D7eUgySO.js";import{y as s}from"./@vue/reactivity-maRK_BBd.js";const U={class:"flex-1"},J=k({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(p,{emit:i}){const f=i,_=p,l=O({get:()=>_.content,set:m=>{f("update:content",m)}});return(m,e)=>{const x=E,c=y,d=b,r=C,v=w,V=I;return B(),F("div",null,[t(V,{"label-width":"70px"},{default:o(()=>[t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[t(c,{label:"标题"},{default:o(()=>[t(x,{class:"w-[396px]",modelValue:s(l).title,"onUpdate:modelValue":e[0]||(e[0]=n=>s(l).title=n)},null,8,["modelValue"])]),_:1})]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[5]||(e[5]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),t(v,{modelValue:s(l).style,"onUpdate:modelValue":e[1]||(e[1]=n=>s(l).style=n)},{default:o(()=>[t(r,{value:1},{default:o(()=>[...e[3]||(e[3]=[u("横排",-1)])]),_:1}),t(r,{value:2},{default:o(()=>[...e[4]||(e[4]=[u("竖排",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"菜单"),a("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),a("div",U,[t(N,{modelValue:s(l).data,"onUpdate:modelValue":e[2]||(e[2]=n=>s(l).data=n)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{J as _};
@@ -1 +1 @@
import{J as C,C as F,I as N,D as O,P as U,Q as g,G as B}from"./element-plus-D-JFNXWu.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-DzYP1kb2.js";import{f as j,ak as d,I as m,a as l,aN as o,J as s,O as x,F as c,ap as v,A as D}from"./@vue/runtime-core-D7eUgySO.js";import{y as n}from"./@vue/reactivity-maRK_BBd.js";const G={class:"flex-1 mt-4"},P=j({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(V,{emit:b}){const y=b,w=V,a=D({get:()=>w.content,set:u=>{y("update:content",u)}});return(u,e)=>{const r=N,E=F,p=g,i=U,_=O,f=C,k=B;return d(),m("div",null,[l(k,{"label-width":"70px"},{default:o(()=>[l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),l(E,{modelValue:n(a).style,"onUpdate:modelValue":e[0]||(e[0]=t=>n(a).style=t)},{default:o(()=>[l(r,{value:1},{default:o(()=>[...e[4]||(e[4]=[x("固定显示",-1)])]),_:1}),l(r,{value:2},{default:o(()=>[...e[5]||(e[5]=[x("分页滑动",-1)])]),_:1})]),_:1},8,["modelValue"]),l(_,{label:"每行数量",class:"mt-4"},{default:o(()=>[l(i,{modelValue:n(a).per_line,"onUpdate:modelValue":e[1]||(e[1]=t=>n(a).per_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(5,t=>l(p,{key:t,label:t+"个",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1}),l(_,{label:"显示行数"},{default:o(()=>[l(i,{modelValue:n(a).show_line,"onUpdate:modelValue":e[2]||(e[2]=t=>n(a).show_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(2,t=>l(p,{key:t,label:t+"行",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1})]),_:1}),l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[7]||(e[7]=s("div",{class:"flex items-end"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单设置"),s("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),s("div",G,[l(I,{modelValue:n(a).data,"onUpdate:modelValue":e[3]||(e[3]=t=>n(a).data=t)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{P as _}; import{J as C,C as F,I as N,D as O,P as U,Q as g,G as B}from"./element-plus-CW0okzRn.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-D35PNbnR.js";import{f as j,ak as d,I as m,a as l,aN as o,J as s,O as x,F as c,ap as v,A as D}from"./@vue/runtime-core-D7eUgySO.js";import{y as n}from"./@vue/reactivity-maRK_BBd.js";const G={class:"flex-1 mt-4"},P=j({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(V,{emit:b}){const y=b,w=V,a=D({get:()=>w.content,set:u=>{y("update:content",u)}});return(u,e)=>{const r=N,E=F,p=g,i=U,_=O,f=C,k=B;return d(),m("div",null,[l(k,{"label-width":"70px"},{default:o(()=>[l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),l(E,{modelValue:n(a).style,"onUpdate:modelValue":e[0]||(e[0]=t=>n(a).style=t)},{default:o(()=>[l(r,{value:1},{default:o(()=>[...e[4]||(e[4]=[x("固定显示",-1)])]),_:1}),l(r,{value:2},{default:o(()=>[...e[5]||(e[5]=[x("分页滑动",-1)])]),_:1})]),_:1},8,["modelValue"]),l(_,{label:"每行数量",class:"mt-4"},{default:o(()=>[l(i,{modelValue:n(a).per_line,"onUpdate:modelValue":e[1]||(e[1]=t=>n(a).per_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(5,t=>l(p,{key:t,label:t+"个",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1}),l(_,{label:"显示行数"},{default:o(()=>[l(i,{modelValue:n(a).show_line,"onUpdate:modelValue":e[2]||(e[2]=t=>n(a).show_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(2,t=>l(p,{key:t,label:t+"行",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1})]),_:1}),l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[7]||(e[7]=s("div",{class:"flex items-end"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单设置"),s("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),s("div",G,[l(I,{modelValue:n(a).data,"onUpdate:modelValue":e[3]||(e[3]=t=>n(a).data=t)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{P as _};
@@ -1 +1 @@
import{J as F,D as I,F as O,g as j,i as A,G}from"./element-plus-D-JFNXWu.js";import{_ as J}from"./index-kKVJiUCL.js";import{b as z,f as g}from"./index-DgHUF7DW.js";import{_ as H}from"./picker-BbSaPsK8.js";import{_ as R}from"./picker-CjRe_gxp.js";import{D as S}from"./vuedraggable-DoxySVw6.js";import{l as v}from"./lodash-es-BADexyn7.js";import{f as T,ak as _,I as b,a as t,aN as a,J as s,G as q,O as K,H as L,A as M}from"./@vue/runtime-core-D7eUgySO.js";import{y as p}from"./@vue/reactivity-maRK_BBd.js";const P={class:"bg-fill-light flex items-center w-full p-4 mt-4"},Q={class:"ml-3 flex-1"},W={class:"flex-1 flex items-center"},X={class:"drag-move cursor-move ml-auto"},Y={key:0,class:"mt-4"},r=5,de=T({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:h}){const c=h,m=u,f=M({get:()=>m.content,set:l=>{c("update:content",l)}}),k=()=>{var l;if(((l=m.content.data)==null?void 0:l.length)<r){const e=v(m.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),c("update:content",e)}else g.msgError(`最多添加${r}张图片`)},w=l=>{var d;if(((d=m.content.data)==null?void 0:d.length)<=1)return g.msgError("最少保留一张图片");const e=v(m.content);e.data.splice(l,1),c("update:content",e)};return(l,e)=>{const d=R,y=O,i=I,E=H,U=j,C=z,D=J,B=A,N=F,$=G;return _(),b("div",null,[t($,{"label-width":"70px"},{default:a(()=>[t(N,{shadow:"never",class:"!border-none flex mt-2"},{default:a(()=>{var x;return[e[2]||(e[2]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单"),s("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),t(p(S),{class:"draggable",modelValue:p(f).data,"onUpdate:modelValue":e[0]||(e[0]=o=>p(f).data=o),animation:"300",handle:".drag-move","item-key":"index"},{item:a(({element:o,index:V})=>[(_(),q(D,{key:V,onClose:n=>w(V),class:"w-[467px]"},{default:a(()=>[s("div",P,[t(d,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),s("div",Q,[t(i,{label:"图片名称"},{default:a(()=>[t(y,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{class:"mt-[18px]",label:"图片链接"},{default:a(()=>[t(E,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{label:"是否显示",class:"mt-[18px]"},{default:a(()=>[s("div",W,[t(U,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),s("div",X,[t(C,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"]),((x=u.content.data)==null?void 0:x.length)<r?(_(),b("div",Y,[t(B,{class:"w-full",type:"primary",onClick:k},{default:a(()=>[...e[1]||(e[1]=[K("添加图片",-1)])]),_:1})])):L("",!0)]}),_:1})]),_:1})])}}});export{de as _}; import{J as F,D as I,F as O,g as j,i as A,G}from"./element-plus-CW0okzRn.js";import{_ as J}from"./index-DuKRmu-Q.js";import{b as z,f as g}from"./index-B-xN0T_Y.js";import{_ as H}from"./picker-Dl86YumP.js";import{_ as R}from"./picker-BTfE-579.js";import{D as S}from"./vuedraggable-DoxySVw6.js";import{l as v}from"./lodash-es-BADexyn7.js";import{f as T,ak as _,I as b,a as t,aN as a,J as s,G as q,O as K,H as L,A as M}from"./@vue/runtime-core-D7eUgySO.js";import{y as p}from"./@vue/reactivity-maRK_BBd.js";const P={class:"bg-fill-light flex items-center w-full p-4 mt-4"},Q={class:"ml-3 flex-1"},W={class:"flex-1 flex items-center"},X={class:"drag-move cursor-move ml-auto"},Y={key:0,class:"mt-4"},r=5,de=T({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:h}){const c=h,m=u,f=M({get:()=>m.content,set:l=>{c("update:content",l)}}),k=()=>{var l;if(((l=m.content.data)==null?void 0:l.length)<r){const e=v(m.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),c("update:content",e)}else g.msgError(`最多添加${r}张图片`)},w=l=>{var d;if(((d=m.content.data)==null?void 0:d.length)<=1)return g.msgError("最少保留一张图片");const e=v(m.content);e.data.splice(l,1),c("update:content",e)};return(l,e)=>{const d=R,y=O,i=I,E=H,U=j,C=z,D=J,B=A,N=F,$=G;return _(),b("div",null,[t($,{"label-width":"70px"},{default:a(()=>[t(N,{shadow:"never",class:"!border-none flex mt-2"},{default:a(()=>{var x;return[e[2]||(e[2]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单"),s("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),t(p(S),{class:"draggable",modelValue:p(f).data,"onUpdate:modelValue":e[0]||(e[0]=o=>p(f).data=o),animation:"300",handle:".drag-move","item-key":"index"},{item:a(({element:o,index:V})=>[(_(),q(D,{key:V,onClose:n=>w(V),class:"w-[467px]"},{default:a(()=>[s("div",P,[t(d,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),s("div",Q,[t(i,{label:"图片名称"},{default:a(()=>[t(y,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{class:"mt-[18px]",label:"图片链接"},{default:a(()=>[t(E,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{label:"是否显示",class:"mt-[18px]"},{default:a(()=>[s("div",W,[t(U,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),s("div",X,[t(C,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"]),((x=u.content.data)==null?void 0:x.length)<r?(_(),b("div",Y,[t(B,{class:"w-full",type:"primary",onClick:k},{default:a(()=>[...e[1]||(e[1]=[K("添加图片",-1)])]),_:1})])):L("",!0)]}),_:1})]),_:1})])}}});export{de as _};
@@ -1 +1 @@
import{_ as o}from"./auth.vue_vue_type_script_setup_true_lang-B3qJR81r.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./menu-BxLrnbbf.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./role-mjnEbF9I.js";import"./index-Cp_4gpIF.js";export{o as default}; import{_ as o}from"./auth.vue_vue_type_script_setup_true_lang-CIqcVQ3F.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./menu-CcCAP22N.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./role-BR31PyDx.js";import"./index-D0yckGv3.js";export{o as default};
@@ -1 +1 @@
import{G as I,s as q,D as J,H as M,W as O,L as P}from"./element-plus-D-JFNXWu.js";import{m as U}from"./menu-BxLrnbbf.js";import{a as W}from"./role-mjnEbF9I.js";import{_ as j}from"./index-Cp_4gpIF.js";import{t as z}from"./index-DgHUF7DW.js";import{f as Q,ak as k,I as X,a,aN as u,aP as Y,G as Z,J as y,n as x}from"./@vue/runtime-core-D7eUgySO.js";import{y as c,a as $,u as f,o as r,r as ee}from"./@vue/reactivity-maRK_BBd.js";const te={class:"edit-popup"},ue=Q({__name:"auth",emits:["success","close"],setup(oe,{expose:C,emit:g}){const _=g,l=f(),h=f(),d=f(),b=r(!1),i=r(!0),m=r(!1),v=r([]),p=r([]),s=ee({id:"",name:"",desc:"",sort:0,menu_id:[]}),E={name:[{required:!0,message:"请输入名称",trigger:["blur"]}]},w=()=>{m.value=!0,U().then(e=>{p.value=e,v.value=z(e),x(()=>{A()}),m.value=!1})},R=()=>{var o,n;const e=(o=l.value)==null?void 0:o.getCheckedKeys(),t=(n=l.value)==null?void 0:n.getHalfCheckedKeys();return e==null||e.unshift.apply(e,t),e},A=()=>{s.menu_id.forEach(e=>{x(()=>{var t;(t=l.value)==null||t.setChecked(e,!0,!1)})})},D=e=>{const t=p.value;for(let o=0;o<t.length;o++)l.value.store.nodesMap[t[o].id].expanded=e},K=e=>{var t,o;e?(t=l.value)==null||t.setCheckedKeys(v.value.map(n=>n.id)):(o=l.value)==null||o.setCheckedKeys([])},V=async()=>{var e,t;await((e=h.value)==null?void 0:e.validate()),s.menu_id=R(),await W(s),(t=d.value)==null||t.close(),_("success")},B=()=>{_("close")},S=()=>{var e;(e=d.value)==null||e.open()},T=async e=>{for(const t in s)e[t]!=null&&e[t]!=null&&(s[t]=e[t])};return w(),C({open:S,setFormData:T}),(e,t)=>{const o=M,n=O,F=J,L=q,N=I,G=P;return k(),X("div",te,[a(j,{ref_key:"popupRef",ref:d,title:"分配权限",async:!0,width:"550px",onConfirm:V,onClose:B},{default:u(()=>[Y((k(),Z(N,{class:"ls-form",ref_key:"formRef",ref:h,rules:E,model:c(s),"label-width":"60px"},{default:u(()=>[a(L,{class:"h-[400px] sm:h-[600px]"},{default:u(()=>[a(F,{label:"权限",prop:"menu_id"},{default:u(()=>[y("div",null,[a(o,{label:"展开/折叠",onChange:D}),a(o,{label:"全选/不全选",onChange:K}),a(o,{modelValue:c(i),"onUpdate:modelValue":t[0]||(t[0]=H=>$(i)?i.value=H:null),label:"父子联动"},null,8,["modelValue"]),y("div",null,[a(n,{ref_key:"treeRef",ref:l,data:c(p),props:{label:"name",children:"children"},"check-strictly":!c(i),"node-key":"id","default-expand-all":c(b),"show-checkbox":""},null,8,["data","check-strictly","default-expand-all"])])])]),_:1})]),_:1})]),_:1},8,["model"])),[[G,c(m)]])]),_:1},512)])}}});export{ue as _}; import{G as I,s as q,D as J,H as M,W as O,L as P}from"./element-plus-CW0okzRn.js";import{m as U}from"./menu-CcCAP22N.js";import{a as W}from"./role-BR31PyDx.js";import{_ as j}from"./index-D0yckGv3.js";import{t as z}from"./index-B-xN0T_Y.js";import{f as Q,ak as k,I as X,a,aN as u,aP as Y,G as Z,J as y,n as x}from"./@vue/runtime-core-D7eUgySO.js";import{y as c,a as $,u as f,o as r,r as ee}from"./@vue/reactivity-maRK_BBd.js";const te={class:"edit-popup"},ue=Q({__name:"auth",emits:["success","close"],setup(oe,{expose:C,emit:g}){const _=g,l=f(),h=f(),d=f(),b=r(!1),i=r(!0),m=r(!1),v=r([]),p=r([]),s=ee({id:"",name:"",desc:"",sort:0,menu_id:[]}),E={name:[{required:!0,message:"请输入名称",trigger:["blur"]}]},w=()=>{m.value=!0,U().then(e=>{p.value=e,v.value=z(e),x(()=>{A()}),m.value=!1})},R=()=>{var o,n;const e=(o=l.value)==null?void 0:o.getCheckedKeys(),t=(n=l.value)==null?void 0:n.getHalfCheckedKeys();return e==null||e.unshift.apply(e,t),e},A=()=>{s.menu_id.forEach(e=>{x(()=>{var t;(t=l.value)==null||t.setChecked(e,!0,!1)})})},D=e=>{const t=p.value;for(let o=0;o<t.length;o++)l.value.store.nodesMap[t[o].id].expanded=e},K=e=>{var t,o;e?(t=l.value)==null||t.setCheckedKeys(v.value.map(n=>n.id)):(o=l.value)==null||o.setCheckedKeys([])},V=async()=>{var e,t;await((e=h.value)==null?void 0:e.validate()),s.menu_id=R(),await W(s),(t=d.value)==null||t.close(),_("success")},B=()=>{_("close")},S=()=>{var e;(e=d.value)==null||e.open()},T=async e=>{for(const t in s)e[t]!=null&&e[t]!=null&&(s[t]=e[t])};return w(),C({open:S,setFormData:T}),(e,t)=>{const o=M,n=O,F=J,L=q,N=I,G=P;return k(),X("div",te,[a(j,{ref_key:"popupRef",ref:d,title:"分配权限",async:!0,width:"550px",onConfirm:V,onClose:B},{default:u(()=>[Y((k(),Z(N,{class:"ls-form",ref_key:"formRef",ref:h,rules:E,model:c(s),"label-width":"60px"},{default:u(()=>[a(L,{class:"h-[400px] sm:h-[600px]"},{default:u(()=>[a(F,{label:"权限",prop:"menu_id"},{default:u(()=>[y("div",null,[a(o,{label:"展开/折叠",onChange:D}),a(o,{label:"全选/不全选",onChange:K}),a(o,{modelValue:c(i),"onUpdate:modelValue":t[0]||(t[0]=H=>$(i)?i.value=H:null),label:"父子联动"},null,8,["modelValue"]),y("div",null,[a(n,{ref_key:"treeRef",ref:l,data:c(p),props:{label:"name",children:"children"},"check-strictly":!c(i),"node-key":"id","default-expand-all":c(b),"show-checkbox":""},null,8,["data","check-strictly","default-expand-all"])])])]),_:1})]),_:1})]),_:1},8,["model"])),[[G,c(m)]])]),_:1},512)])}}});export{ue as _};
@@ -1 +1 @@
import{K as L,G as N,D as K,F as I,P as O,Q as z,i as G,J,M as Q,N as R,L as S}from"./element-plus-D-JFNXWu.js";import{_ as $}from"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import{_ as j}from"./index-DgHUF7DW.js";import{_ as q}from"./index.vue_vue_type_script_setup_true_lang-Deqsk8s7.js";import{w as A}from"./@vue/runtime-dom-DVgibYoU.js";import{a as M,g as H}from"./finance-CUXau4L5.js";import{u as W}from"./useDictOptions-CdSSP3gL.js";import{u as X}from"./usePaging-CPrBIeJ2.js";import{f as v,ak as s,I as h,a as e,aN as n,F as Y,ap as Z,G as w,O as p,aP as ee,J as _}from"./@vue/runtime-core-D7eUgySO.js";import{y as o,a as te,r as oe}from"./@vue/reactivity-maRK_BBd.js";import{Q as y,o as ae}from"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./nprogress-BpICrWuH.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const ne={class:"flex items-center"},le={class:"flex justify-end mt-4"},ie=v({name:"balanceDetail"}),He=v({...ie,setup(re){const l=oe({user_info:"",change_type:"",start_time:"",end_time:""}),{pager:r,getLists:d,resetPage:c,resetParams:x}=X({fetchFun:M,params:l}),{optionsData:C}=W({change_type:{api:H}});return d(),(me,a)=>{const V=L,E=I,m=K,u=z,T=O,k=q,f=G,D=N,g=J,i=R,F=j,P=Q,U=$,B=S;return s(),h("div",null,[e(g,{class:"!border-none",shadow:"never"},{default:n(()=>[e(V,{type:"warning",title:"温馨提示:用户账户变动记录",closable:!1,"show-icon":""}),e(D,{ref:"formRef",class:"mb-[-16px] mt-[16px]",model:o(l),inline:!0},{default:n(()=>[e(m,{class:"w-[280px]",label:"用户信息"},{default:n(()=>[e(E,{modelValue:o(l).user_info,"onUpdate:modelValue":a[0]||(a[0]=t=>o(l).user_info=t),placeholder:"请输入用户账号/昵称/手机号",clearable:"",onKeyup:A(o(c),["enter"])},null,8,["modelValue","onKeyup"])]),_:1}),e(m,{class:"w-[280px]",label:"变动类型"},{default:n(()=>[e(T,{modelValue:o(l).change_type,"onUpdate:modelValue":a[1]||(a[1]=t=>o(l).change_type=t)},{default:n(()=>[e(u,{label:"全部",value:""}),(s(!0),h(Y,null,Z(o(C).change_type,(t,b)=>(s(),w(u,{key:b,label:t,value:b},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),e(m,{label:"记录时间"},{default:n(()=>[e(k,{startTime:o(l).start_time,"onUpdate:startTime":a[2]||(a[2]=t=>o(l).start_time=t),endTime:o(l).end_time,"onUpdate:endTime":a[3]||(a[3]=t=>o(l).end_time=t)},null,8,["startTime","endTime"])]),_:1}),e(m,null,{default:n(()=>[e(f,{type:"primary",onClick:o(c)},{default:n(()=>[...a[5]||(a[5]=[p("查询",-1)])]),_:1},8,["onClick"]),e(f,{onClick:o(x)},{default:n(()=>[...a[6]||(a[6]=[p("重置",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["model"])]),_:1}),e(g,{class:"!border-none mt-4",shadow:"never"},{default:n(()=>[ee((s(),w(P,{size:"large",data:o(r).lists},{default:n(()=>[e(i,{label:"用户账号",prop:"account","min-width":"100"}),e(i,{label:"用户昵称","min-width":"160"},{default:n(({row:t})=>[_("div",ne,[e(F,{class:"flex-none mr-2",src:t.avatar,width:40,height:40,"preview-teleported":"",fit:"contain"},null,8,["src"]),p(" "+y(t.nickname),1)])]),_:1}),e(i,{label:"手机号码",prop:"mobile","min-width":"100"}),e(i,{label:"变动金额",prop:"change_amount","min-width":"100"},{default:n(({row:t})=>[_("span",{class:ae({"text-error":t.action==2})},y(t.change_amount),3)]),_:1}),e(i,{label:"剩余金额",prop:"left_amount","min-width":"100"}),e(i,{label:"变动类型",prop:"change_type_desc","min-width":"120"}),e(i,{label:"来源单号",prop:"source_sn","min-width":"100"}),e(i,{label:"记录时间",prop:"create_time","min-width":"120"})]),_:1},8,["data"])),[[B,o(r).loading]]),_("div",le,[e(U,{modelValue:o(r),"onUpdate:modelValue":a[4]||(a[4]=t=>te(r)?r.value=t:null),onChange:o(d)},null,8,["modelValue","onChange"])])]),_:1})])}}});export{He as default}; import{K as L,G as N,D as K,F as I,P as O,Q as z,i as G,J,M as Q,N as R,L as S}from"./element-plus-CW0okzRn.js";import{_ as $}from"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import{_ as j}from"./index-B-xN0T_Y.js";import{_ as q}from"./index.vue_vue_type_script_setup_true_lang-BaCcK1hf.js";import{w as A}from"./@vue/runtime-dom-DVgibYoU.js";import{a as M,g as H}from"./finance-Bxhu92mA.js";import{u as W}from"./useDictOptions-C_34sxAY.js";import{u as X}from"./usePaging-CPrBIeJ2.js";import{f as v,ak as s,I as h,a as e,aN as n,F as Y,ap as Z,G as w,O as p,aP as ee,J as _}from"./@vue/runtime-core-D7eUgySO.js";import{y as o,a as te,r as oe}from"./@vue/reactivity-maRK_BBd.js";import{Q as y,o as ae}from"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./nprogress-BpICrWuH.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const ne={class:"flex items-center"},le={class:"flex justify-end mt-4"},ie=v({name:"balanceDetail"}),He=v({...ie,setup(re){const l=oe({user_info:"",change_type:"",start_time:"",end_time:""}),{pager:r,getLists:d,resetPage:c,resetParams:x}=X({fetchFun:M,params:l}),{optionsData:C}=W({change_type:{api:H}});return d(),(me,a)=>{const V=L,E=I,m=K,u=z,T=O,k=q,f=G,D=N,g=J,i=R,F=j,P=Q,U=$,B=S;return s(),h("div",null,[e(g,{class:"!border-none",shadow:"never"},{default:n(()=>[e(V,{type:"warning",title:"温馨提示:用户账户变动记录",closable:!1,"show-icon":""}),e(D,{ref:"formRef",class:"mb-[-16px] mt-[16px]",model:o(l),inline:!0},{default:n(()=>[e(m,{class:"w-[280px]",label:"用户信息"},{default:n(()=>[e(E,{modelValue:o(l).user_info,"onUpdate:modelValue":a[0]||(a[0]=t=>o(l).user_info=t),placeholder:"请输入用户账号/昵称/手机号",clearable:"",onKeyup:A(o(c),["enter"])},null,8,["modelValue","onKeyup"])]),_:1}),e(m,{class:"w-[280px]",label:"变动类型"},{default:n(()=>[e(T,{modelValue:o(l).change_type,"onUpdate:modelValue":a[1]||(a[1]=t=>o(l).change_type=t)},{default:n(()=>[e(u,{label:"全部",value:""}),(s(!0),h(Y,null,Z(o(C).change_type,(t,b)=>(s(),w(u,{key:b,label:t,value:b},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),e(m,{label:"记录时间"},{default:n(()=>[e(k,{startTime:o(l).start_time,"onUpdate:startTime":a[2]||(a[2]=t=>o(l).start_time=t),endTime:o(l).end_time,"onUpdate:endTime":a[3]||(a[3]=t=>o(l).end_time=t)},null,8,["startTime","endTime"])]),_:1}),e(m,null,{default:n(()=>[e(f,{type:"primary",onClick:o(c)},{default:n(()=>[...a[5]||(a[5]=[p("查询",-1)])]),_:1},8,["onClick"]),e(f,{onClick:o(x)},{default:n(()=>[...a[6]||(a[6]=[p("重置",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["model"])]),_:1}),e(g,{class:"!border-none mt-4",shadow:"never"},{default:n(()=>[ee((s(),w(P,{size:"large",data:o(r).lists},{default:n(()=>[e(i,{label:"用户账号",prop:"account","min-width":"100"}),e(i,{label:"用户昵称","min-width":"160"},{default:n(({row:t})=>[_("div",ne,[e(F,{class:"flex-none mr-2",src:t.avatar,width:40,height:40,"preview-teleported":"",fit:"contain"},null,8,["src"]),p(" "+y(t.nickname),1)])]),_:1}),e(i,{label:"手机号码",prop:"mobile","min-width":"100"}),e(i,{label:"变动金额",prop:"change_amount","min-width":"100"},{default:n(({row:t})=>[_("span",{class:ae({"text-error":t.action==2})},y(t.change_amount),3)]),_:1}),e(i,{label:"剩余金额",prop:"left_amount","min-width":"100"}),e(i,{label:"变动类型",prop:"change_type_desc","min-width":"120"}),e(i,{label:"来源单号",prop:"source_sn","min-width":"100"}),e(i,{label:"记录时间",prop:"create_time","min-width":"120"})]),_:1},8,["data"])),[[B,o(r).loading]]),_("div",le,[e(U,{modelValue:o(r),"onUpdate:modelValue":a[4]||(a[4]=t=>te(r)?r.value=t:null),onChange:o(d)},null,8,["modelValue","onChange"])])]),_:1})])}}});export{He as default};
@@ -1 +1 @@
import{K as c,J as _,M as d,N as f,i as u}from"./element-plus-D-JFNXWu.js";import{f as h,v as b}from"./index-DgHUF7DW.js";import{f as i,ak as w,I as C,a as t,aN as o,O as k}from"./@vue/runtime-core-D7eUgySO.js";import{y,o as E}from"./@vue/reactivity-maRK_BBd.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const x={class:"cache"},v=i({name:"cache"}),pt=i({...v,setup(N){const n=E([{content:"系统缓存",desc:"系统运行过程中产生的各类缓存数据"}]),m=async()=>{await h.confirm("确认清除系统缓存?"),await b(),window.location.reload()};return(g,a)=>{const p=c,r=_,e=f,l=u,s=d;return w(),C("div",x,[t(r,{class:"!border-none",shadow:"never"},{default:o(()=>[t(p,{type:"warning",title:"温馨提示:管理系统运行过程中产生的缓存",closable:!1,"show-icon":""})]),_:1}),t(r,{class:"!border-none mt-4",shadow:"never"},{default:o(()=>[t(s,{data:y(n),size:"large"},{default:o(()=>[t(e,{label:"管理内容",prop:"content","min-width":"130"}),t(e,{label:"内容说明",prop:"desc","min-width":"180"}),t(e,{label:"操作",width:"130",fixed:"right"},{default:o(()=>[t(l,{type:"primary",link:"",onClick:m},{default:o(()=>[...a[0]||(a[0]=[k("清除系统缓存",-1)])]),_:1})]),_:1})]),_:1},8,["data"])]),_:1})])}}});export{pt as default}; import{K as c,J as _,M as d,N as f,i as u}from"./element-plus-CW0okzRn.js";import{f as h,v as b}from"./index-B-xN0T_Y.js";import{f as i,ak as w,I as C,a as t,aN as o,O as k}from"./@vue/runtime-core-D7eUgySO.js";import{y,o as E}from"./@vue/reactivity-maRK_BBd.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const x={class:"cache"},v=i({name:"cache"}),pt=i({...v,setup(N){const n=E([{content:"系统缓存",desc:"系统运行过程中产生的各类缓存数据"}]),m=async()=>{await h.confirm("确认清除系统缓存?"),await b(),window.location.reload()};return(g,a)=>{const p=c,r=_,e=f,l=u,s=d;return w(),C("div",x,[t(r,{class:"!border-none",shadow:"never"},{default:o(()=>[t(p,{type:"warning",title:"温馨提示:管理系统运行过程中产生的缓存",closable:!1,"show-icon":""})]),_:1}),t(r,{class:"!border-none mt-4",shadow:"never"},{default:o(()=>[t(s,{data:y(n),size:"large"},{default:o(()=>[t(e,{label:"管理内容",prop:"content","min-width":"130"}),t(e,{label:"内容说明",prop:"desc","min-width":"180"}),t(e,{label:"操作",width:"130",fixed:"right"},{default:o(()=>[t(l,{type:"primary",link:"",onClick:m},{default:o(()=>[...a[0]||(a[0]=[k("清除系统缓存",-1)])]),_:1})]),_:1})]),_:1},8,["data"])]),_:1})])}}});export{pt as default};
@@ -1 +1 @@
import{r as t}from"./index-DgHUF7DW.js";function o(e){return t.get({url:"/tools.generator/generateTable",params:e})}function n(e){return t.get({url:"/tools.generator/dataTable",params:e})}function a(e){return t.post({url:"/tools.generator/selectTable",params:e})}function l(e){return t.get({url:"/tools.generator/detail",params:e})}function s(e){return t.post({url:"/tools.generator/syncColumn",params:e})}function u(e){return t.post({url:"/tools.generator/delete",params:e})}function g(e){return t.post({url:"/tools.generator/edit",params:e})}function i(e){return t.post({url:"/tools.generator/preview",params:e})}function c(e){return t.post({url:"/tools.generator/generate",params:e})}function f(){return t.get({url:"/tools.generator/getModels"})}export{f as a,o as b,u as c,i as d,c as e,n as f,g,a as h,s,l as t}; import{r as t}from"./index-B-xN0T_Y.js";function o(e){return t.get({url:"/tools.generator/generateTable",params:e})}function n(e){return t.get({url:"/tools.generator/dataTable",params:e})}function a(e){return t.post({url:"/tools.generator/selectTable",params:e})}function l(e){return t.get({url:"/tools.generator/detail",params:e})}function s(e){return t.post({url:"/tools.generator/syncColumn",params:e})}function u(e){return t.post({url:"/tools.generator/delete",params:e})}function g(e){return t.post({url:"/tools.generator/edit",params:e})}function i(e){return t.post({url:"/tools.generator/preview",params:e})}function c(e){return t.post({url:"/tools.generator/generate",params:e})}function f(){return t.get({url:"/tools.generator/getModels"})}export{f as a,o as b,u as c,i as d,c as e,n as f,g,a as h,s,l as t};
@@ -1 +1 @@
import{_ as o}from"./code-preview.vue_vue_type_script_setup_true_lang-BmfRN0ln.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default}; import{_ as o}from"./code-preview.vue_vue_type_script_setup_true_lang-Cc7lcPHH.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default};
@@ -1 +1 @@
import{m as B,l as T,s as N,i as $,T as j}from"./element-plus-D-JFNXWu.js";import{b as D,f as d}from"./index-DgHUF7DW.js";import{u as F}from"./vue-clipboard3-ChYu0NfX.js";import{f as S,ar as U,ak as c,I as i,a as t,aN as a,F as A,ap as G,G as I,J as u,O as J,A as L}from"./@vue/runtime-core-D7eUgySO.js";import{a as p,y as _,o as O}from"./@vue/reactivity-maRK_BBd.js";const P={class:"code-preview"},R={class:"flex",style:{height:"50vh"}},W=S({__name:"code-preview",props:{modelValue:{type:Boolean},code:{}},emits:["update:modelValue"],setup(r,{emit:f}){const b=r,V=f,{toClipboard:g}=F(),n=O("index0"),h=async l=>{try{await g(l),d.msgSuccess("复制成功")}catch{d.msgError("复制失败")}},s=L({get(){return b.modelValue},set(l){V("update:modelValue",l)}});return(l,e)=>{const v=U("highlightjs"),y=N,k=D,C=$,x=T,E=B,w=j;return c(),i("div",P,[t(w,{modelValue:_(s),"onUpdate:modelValue":e[1]||(e[1]=o=>p(s)?s.value=o:null),width:"900px",title:"代码预览"},{default:a(()=>[t(E,{modelValue:_(n),"onUpdate:modelValue":e[0]||(e[0]=o=>p(n)?n.value=o:null)},{default:a(()=>[(c(!0),i(A,null,G(r.code,(o,m)=>(c(),I(x,{label:o.name,name:`index${m}`,key:m},{default:a(()=>[u("div",R,[t(y,{class:"flex-1"},{default:a(()=>[t(v,{autodetect:"",code:o.content},null,8,["code"])]),_:2},1024),u("div",null,[t(C,{onClick:q=>h(o.content),type:"primary",link:""},{icon:a(()=>[t(k,{name:"el-icon-CopyDocument"})]),default:a(()=>[e[2]||(e[2]=J(" 复制 ",-1))]),_:1},8,["onClick"])])])]),_:2},1032,["label","name"]))),128))]),_:1},8,["modelValue"])]),_:1},8,["modelValue"])])}}});export{W as _}; import{m as B,l as T,s as N,i as $,T as j}from"./element-plus-CW0okzRn.js";import{b as D,f as d}from"./index-B-xN0T_Y.js";import{u as F}from"./vue-clipboard3-ChYu0NfX.js";import{f as S,ar as U,ak as c,I as i,a as t,aN as a,F as A,ap as G,G as I,J as u,O as J,A as L}from"./@vue/runtime-core-D7eUgySO.js";import{a as p,y as _,o as O}from"./@vue/reactivity-maRK_BBd.js";const P={class:"code-preview"},R={class:"flex",style:{height:"50vh"}},W=S({__name:"code-preview",props:{modelValue:{type:Boolean},code:{}},emits:["update:modelValue"],setup(r,{emit:f}){const b=r,V=f,{toClipboard:g}=F(),n=O("index0"),h=async l=>{try{await g(l),d.msgSuccess("复制成功")}catch{d.msgError("复制失败")}},s=L({get(){return b.modelValue},set(l){V("update:modelValue",l)}});return(l,e)=>{const v=U("highlightjs"),y=N,k=D,C=$,x=T,E=B,w=j;return c(),i("div",P,[t(w,{modelValue:_(s),"onUpdate:modelValue":e[1]||(e[1]=o=>p(s)?s.value=o:null),width:"900px",title:"代码预览"},{default:a(()=>[t(E,{modelValue:_(n),"onUpdate:modelValue":e[0]||(e[0]=o=>p(n)?n.value=o:null)},{default:a(()=>[(c(!0),i(A,null,G(r.code,(o,m)=>(c(),I(x,{label:o.name,name:`index${m}`,key:m},{default:a(()=>[u("div",R,[t(y,{class:"flex-1"},{default:a(()=>[t(v,{autodetect:"",code:o.content},null,8,["code"])]),_:2},1024),u("div",null,[t(C,{onClick:q=>h(o.content),type:"primary",link:""},{icon:a(()=>[t(k,{name:"el-icon-CopyDocument"})]),default:a(()=>[e[2]||(e[2]=J(" 复制 ",-1))]),_:1},8,["onClick"])])])]),_:2},1032,["label","name"]))),128))]),_:1},8,["modelValue"])]),_:1},8,["modelValue"])])}}});export{W as _};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{r}from"./index-DgHUF7DW.js";function u(e){return r.get({url:"/user.user/lists",params:e},{ignoreCancelToken:!0})}function s(e){return r.get({url:"/user.user/detail",params:e})}function n(e){return r.post({url:"/user.user/edit",params:e})}function o(e){return r.post({url:"/user.user/adjustMoney",params:e})}export{o as a,u as b,s as g,n as u}; import{r}from"./index-B-xN0T_Y.js";function u(e){return r.get({url:"/user.user/lists",params:e},{ignoreCancelToken:!0})}function s(e){return r.get({url:"/user.user/detail",params:e})}function n(e){return r.post({url:"/user.user/edit",params:e})}function o(e){return r.post({url:"/user.user/adjustMoney",params:e})}export{o as a,u as b,s as g,n as u};
@@ -1 +1 @@
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-B5-3GwBf.js";import"./decoration-img-CttNGVCW.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default}; import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-Lx1f1O3E.js";import"./decoration-img-CC8K0JZ3.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-CyJb5BW9.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-kKVJiUCL.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-BbSaPsK8.js";import"./index-Cp_4gpIF.js";import"./index.vue_vue_type_script_setup_true_lang-D8oSSfxQ.js";import"./article-CLsBk2Mb.js";import"./usePaging-CPrBIeJ2.js";import"./picker-CjRe_gxp.js";import"./index-BatBRS96.js";import"./index-DempaqRP.js";import"./index.vue_vue_type_script_setup_true_lang-CvzbbNi4.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default}; import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-BELbd7NG.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DuKRmu-Q.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";import"./picker-Dl86YumP.js";import"./index-D0yckGv3.js";import"./index.vue_vue_type_script_setup_true_lang-DiGHetBS.js";import"./article-85L4UaQJ.js";import"./usePaging-CPrBIeJ2.js";import"./picker-BTfE-579.js";import"./index-BZIFSND_.js";import"./index-lZTBZPpA.js";import"./index.vue_vue_type_script_setup_true_lang-DJ9KkFch.js";import"./vuedraggable-DoxySVw6.js";import"./vue-BWLcg9DT.js";import"./@vue/compiler-dom-Ddn9Zm90.js";import"./@vue/compiler-core-KYniu4wC.js";import"./sortablejs-BkVvOzsn.js";export{o as default};
@@ -1 +1 @@
import{d as t}from"./index-DgHUF7DW.js";import{ak as o,I as r}from"./@vue/runtime-core-D7eUgySO.js";import"./nprogress-BpICrWuH.js";import"./vue-router-CJXI7XhX.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const m={},i={class:"page-mate"};function p(e,c){return o(),r("div",i)}const Q=t(m,[["render",p]]);export{Q as default}; import{d as t}from"./index-B-xN0T_Y.js";import{ak as o,I as r}from"./@vue/runtime-core-D7eUgySO.js";import"./nprogress-BpICrWuH.js";import"./vue-router-CJXI7XhX.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const m={},i={class:"page-mate"};function p(e,c){return o(),r("div",i)}const Q=t(m,[["render",p]]);export{Q as default};
@@ -1 +1 @@
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-B2hMMnZ0.js";import"./decoration-img-CttNGVCW.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default}; import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-mR0br7S_.js";import"./decoration-img-CC8K0JZ3.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default};
@@ -1 +1 @@
import s from"./decoration-img-CttNGVCW.js";import{f as p,ak as r,I as m,J as e,a as c,H as n,O as a,F as l}from"./@vue/runtime-core-D7eUgySO.js";import{Q as i}from"./@vue/shared-C75lBtbe.js";import{d as x}from"./index-DgHUF7DW.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/reactivity-maRK_BBd.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const d={class:"customer-service bg-white flex flex-col justify-center items-center mx-[18px] mt-[15px] rounded-[10px] px-[10px] pb-[50px]"},f={class:"w-full border-solid border-0 border-b border-[#f5f5f5] p-[15px] text-center text-[#101010] text-base font-medium"},u={class:"mt-[30px]"},b={key:0,class:"text-sm mt-[20px] font-medium"},h={key:1,class:"text-sm mt-[12px] flex flex-wrap"},w=["href"],v={key:2,class:"text-muted text-sm mt-[15px]"},y=p({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(t){return(k,o)=>(r(),m(l,null,[o[0]||(o[0]=e("view",{class:"bg-white p-[15px] flex text-[#101010] font-medium text-lg"}," 联系我们 ",-1)),e("view",d,[e("view",f,i(t.content.title),1),e("view",u,[c(s,{width:"100px",height:"100px",src:t.content.qrcode,alt:""},null,8,["src"])]),t.content.remark?(r(),m("view",b,i(t.content.remark),1)):n("",!0),t.content.mobile?(r(),m("view",h,[e("a",{class:"ml-[5px] phone text-primary underline",href:"tel:"+t.content.mobile},i(t.content.mobile),9,w)])):n("",!0),t.content.time?(r(),m("view",v," 服务时间:"+i(t.content.time),1)):n("",!0)]),o[1]||(o[1]=a(" Î ",-1))],64))}}),mt=x(y,[["__scopeId","data-v-ed28524a"]]);export{mt as default}; import s from"./decoration-img-CC8K0JZ3.js";import{f as p,ak as r,I as m,J as e,a as c,H as n,O as a,F as l}from"./@vue/runtime-core-D7eUgySO.js";import{Q as i}from"./@vue/shared-C75lBtbe.js";import{d as x}from"./index-B-xN0T_Y.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/reactivity-maRK_BBd.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const d={class:"customer-service bg-white flex flex-col justify-center items-center mx-[18px] mt-[15px] rounded-[10px] px-[10px] pb-[50px]"},f={class:"w-full border-solid border-0 border-b border-[#f5f5f5] p-[15px] text-center text-[#101010] text-base font-medium"},u={class:"mt-[30px]"},b={key:0,class:"text-sm mt-[20px] font-medium"},h={key:1,class:"text-sm mt-[12px] flex flex-wrap"},w=["href"],v={key:2,class:"text-muted text-sm mt-[15px]"},y=p({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(t){return(k,o)=>(r(),m(l,null,[o[0]||(o[0]=e("view",{class:"bg-white p-[15px] flex text-[#101010] font-medium text-lg"}," 联系我们 ",-1)),e("view",d,[e("view",f,i(t.content.title),1),e("view",u,[c(s,{width:"100px",height:"100px",src:t.content.qrcode,alt:""},null,8,["src"])]),t.content.remark?(r(),m("view",b,i(t.content.remark),1)):n("",!0),t.content.mobile?(r(),m("view",h,[e("a",{class:"ml-[5px] phone text-primary underline",href:"tel:"+t.content.mobile},i(t.content.mobile),9,w)])):n("",!0),t.content.time?(r(),m("view",v," 服务时间:"+i(t.content.time),1)):n("",!0)]),o[1]||(o[1]=a(" Î ",-1))],64))}}),mt=x(y,[["__scopeId","data-v-ed28524a"]]);export{mt as default};
@@ -1 +1 @@
import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-FaipDzzu.js";import"./decoration-img-CttNGVCW.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DgHUF7DW.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default}; import{_ as o}from"./content.vue_vue_type_script_setup_true_lang-DRsiE0N3.js";import"./decoration-img-CC8K0JZ3.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/runtime-core-D7eUgySO.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-B-xN0T_Y.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";export{o as default};
@@ -1 +1 @@
import c from"./decoration-img-CttNGVCW.js";import{f as n,ak as r,I as o,F as l,ap as f,a as d,J as u,A as _}from"./@vue/runtime-core-D7eUgySO.js";import{p as x,Q as y}from"./@vue/shared-C75lBtbe.js";import{y as b}from"./@vue/reactivity-maRK_BBd.js";import{d as h}from"./index-DgHUF7DW.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const g={class:"tabbar flex"},v={class:"leading-3 text-[12px] mt-[4px]"},k=n({__name:"content",props:{style:{type:Object,default:()=>({})},list:{type:Array,default:()=>[]}},setup(e){const m=e,s=_(()=>{var t;return((t=m.list)==null?void 0:t.filter(i=>i.is_show==1))||[]});return(t,i)=>(r(),o("div",g,[(r(!0),o(l,null,f(b(s),(p,a)=>(r(),o("div",{key:a,class:"tabbar-item flex flex-col justify-center items-center flex-1",style:x({color:e.style.default_color})},[d(c,{width:"22px",height:"22px",src:p.unselected,fit:"cover"},null,8,["src"]),u("div",v,y(p.name),1)],4))),128))]))}}),pt=h(k,[["__scopeId","data-v-0405bccb"]]);export{pt as default}; import c from"./decoration-img-CC8K0JZ3.js";import{f as n,ak as r,I as o,F as l,ap as f,a as d,J as u,A as _}from"./@vue/runtime-core-D7eUgySO.js";import{p as x,Q as y}from"./@vue/shared-C75lBtbe.js";import{y as b}from"./@vue/reactivity-maRK_BBd.js";import{d as h}from"./index-B-xN0T_Y.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const g={class:"tabbar flex"},v={class:"leading-3 text-[12px] mt-[4px]"},k=n({__name:"content",props:{style:{type:Object,default:()=>({})},list:{type:Array,default:()=>[]}},setup(e){const m=e,s=_(()=>{var t;return((t=m.list)==null?void 0:t.filter(i=>i.is_show==1))||[]});return(t,i)=>(r(),o("div",g,[(r(!0),o(l,null,f(b(s),(p,a)=>(r(),o("div",{key:a,class:"tabbar-item flex flex-col justify-center items-center flex-1",style:x({color:e.style.default_color})},[d(c,{width:"22px",height:"22px",src:p.unselected,fit:"cover"},null,8,["src"]),u("div",v,y(p.name),1)],4))),128))]))}}),pt=h(k,[["__scopeId","data-v-0405bccb"]]);export{pt as default};
@@ -1 +1 @@
import{b as c,d as n}from"./index-DgHUF7DW.js";import{g as l}from"./decoration-CfOm5lOP.js";import{f as d,ak as o,I as s,J as t,F as _,ap as x,H as f,a as u}from"./@vue/runtime-core-D7eUgySO.js";import{Q as i}from"./@vue/shared-C75lBtbe.js";import{y as v,o as y}from"./@vue/reactivity-maRK_BBd.js";import"./nprogress-BpICrWuH.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const b={class:"news"},w={key:0,class:"mr-[10px]"},g=["src"],h={class:"flex flex-col justify-between flex-1"},k={class:"text-[15px] font-medium line-clamp-2"},j={class:"line-clamp-1 text-sm mt-[8px]"},D={class:"text-[#999] text-xs w-full flex justify-between mt-[8px]"},V={class:"flex items-center"},B={class:"ml-[5px]"},N=d({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(C){const r=y([]);return(async()=>{const p=await l({limit:10});r.value=p})(),(p,m)=>{const a=c;return o(),s("div",b,[m[0]||(m[0]=t("div",{class:"flex items-center news-title mx-[10px] my-[15px] text-[17px] font-medium"}," 最新资讯 ",-1)),(o(!0),s(_,null,x(v(r),e=>(o(),s("div",{key:e.id,class:"news-card flex bg-white px-[10px] py-[16px] text-[#333] border-[#f2f2f2] border-b"},[e.image?(o(),s("div",w,[t("img",{src:e.image,class:"w-[120px] h-[90px] object-contain"},null,8,g)])):f("",!0),t("div",h,[t("div",k,i(e.title),1),t("div",j,i(e.desc),1),t("div",D,[t("div",null,i(e.create_time),1),t("div",V,[u(a,{name:"el-icon-View"}),t("div",B,i(e.click),1)])])])]))),128))])}}}),_t=n(N,[["__scopeId","data-v-dba98882"]]);export{_t as default}; import{b as c,d as n}from"./index-B-xN0T_Y.js";import{g as l}from"./decoration-DcrKh-Qh.js";import{f as d,ak as o,I as s,J as t,F as _,ap as x,H as f,a as u}from"./@vue/runtime-core-D7eUgySO.js";import{Q as i}from"./@vue/shared-C75lBtbe.js";import{y as v,o as y}from"./@vue/reactivity-maRK_BBd.js";import"./nprogress-BpICrWuH.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const b={class:"news"},w={key:0,class:"mr-[10px]"},g=["src"],h={class:"flex flex-col justify-between flex-1"},k={class:"text-[15px] font-medium line-clamp-2"},j={class:"line-clamp-1 text-sm mt-[8px]"},D={class:"text-[#999] text-xs w-full flex justify-between mt-[8px]"},V={class:"flex items-center"},B={class:"ml-[5px]"},N=d({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(C){const r=y([]);return(async()=>{const p=await l({limit:10});r.value=p})(),(p,m)=>{const a=c;return o(),s("div",b,[m[0]||(m[0]=t("div",{class:"flex items-center news-title mx-[10px] my-[15px] text-[17px] font-medium"}," 最新资讯 ",-1)),(o(!0),s(_,null,x(v(r),e=>(o(),s("div",{key:e.id,class:"news-card flex bg-white px-[10px] py-[16px] text-[#333] border-[#f2f2f2] border-b"},[e.image?(o(),s("div",w,[t("img",{src:e.image,class:"w-[120px] h-[90px] object-contain"},null,8,g)])):f("",!0),t("div",h,[t("div",k,i(e.title),1),t("div",j,i(e.desc),1),t("div",D,[t("div",null,i(e.create_time),1),t("div",V,[u(a,{name:"el-icon-View"}),t("div",B,i(e.click),1)])])])]))),128))])}}}),_t=n(N,[["__scopeId","data-v-dba98882"]]);export{_t as default};
@@ -1 +1 @@
import{d as r}from"./index-DgHUF7DW.js";import{ak as p,I as i,J as o}from"./@vue/runtime-core-D7eUgySO.js";import"./nprogress-BpICrWuH.js";import"./vue-router-CJXI7XhX.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const m="/admin/assets/default_avatar-C6VB7PGm.png",e={},s={class:"user-info flex items-center px-[25px]"};function a(n,t){return p(),i("div",s,[...t[0]||(t[0]=[o("img",{src:m,class:"w-[60px] h-[60px]",alt:""},null,-1),o("div",{class:"text-white text-[18px] ml-[10px]"},"未登录",-1)])])}const R=r(e,[["render",a],["__scopeId","data-v-4b1b613f"]]);export{R as default}; import{d as r}from"./index-B-xN0T_Y.js";import{ak as p,I as i,J as o}from"./@vue/runtime-core-D7eUgySO.js";import"./nprogress-BpICrWuH.js";import"./vue-router-CJXI7XhX.js";import"./@vue/reactivity-maRK_BBd.js";import"./@vue/shared-C75lBtbe.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const m="/admin/assets/default_avatar-C6VB7PGm.png",e={},s={class:"user-info flex items-center px-[25px]"};function a(n,t){return p(),i("div",s,[...t[0]||(t[0]=[o("img",{src:m,class:"w-[60px] h-[60px]",alt:""},null,-1),o("div",{class:"text-white text-[18px] ml-[10px]"},"未登录",-1)])])}const R=r(e,[["render",a],["__scopeId","data-v-4b1b613f"]]);export{R as default};
@@ -1 +1 @@
import{s as _}from"./element-plus-D-JFNXWu.js";import l from"./decoration-img-CttNGVCW.js";import{f,ak as r,I as e,a as p,aN as a,J as t,F as m,ap as c,H as v}from"./@vue/runtime-core-D7eUgySO.js";import{o as h,Q as d}from"./@vue/shared-C75lBtbe.js";import{d as x}from"./index-DgHUF7DW.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/reactivity-maRK_BBd.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const y={class:"pc-aside absolute top-0 bottom-0 left-0 w-[150px]"},k={class:"h-full px-[10px] flex flex-col"},b={class:"mb-auto"},g={class:"nav"},w=["to"],C={class:"ml-[10px]"},N={class:"menu"},B={class:"ml-[6px] line-clamp-1"},E=f({__name:"content",props:{nav:{type:Array,default:()=>[]},menu:{type:Array,default:()=>[]}},setup(n){return(I,i)=>{const u=_;return r(),e("div",y,[p(u,null,{default:a(()=>[t("div",k,[t("div",b,[t("div",g,[(r(!0),e(m,null,c(n.nav,(o,s)=>(r(),e(m,{key:s},[o.is_show=="1"?(r(),e("div",{key:0,to:o.link.path,class:h(["nav-item",{active:s==0}])},[p(l,{width:"18px",height:"18px",src:s==0?o.selected:o.unselected,fit:"cover"},{error:a(()=>[...i[0]||(i[0]=[t("span",null,null,-1)])]),_:1},8,["src"]),t("div",C,d(o.name),1)],10,w)):v("",!0)],64))),128))])]),t("div",null,[t("div",N,[(r(!0),e(m,null,c(n.menu,(o,s)=>(r(),e("div",{class:"menu-item",key:s},[p(l,{width:"16px",height:"16px",src:o.unselected,fit:"cover"},{error:a(()=>[...i[1]||(i[1]=[t("span",null,null,-1)])]),_:1},8,["src"]),t("span",B,d(o.name),1)]))),128))])])])]),_:1})])}}}),ct=x(E,[["__scopeId","data-v-35c14957"]]);export{ct as default}; import{s as _}from"./element-plus-CW0okzRn.js";import l from"./decoration-img-CC8K0JZ3.js";import{f,ak as r,I as e,a as p,aN as a,J as t,F as m,ap as c,H as v}from"./@vue/runtime-core-D7eUgySO.js";import{o as h,Q as d}from"./@vue/shared-C75lBtbe.js";import{d as x}from"./index-B-xN0T_Y.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./nprogress-BpICrWuH.js";import"./@vue/reactivity-maRK_BBd.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const y={class:"pc-aside absolute top-0 bottom-0 left-0 w-[150px]"},k={class:"h-full px-[10px] flex flex-col"},b={class:"mb-auto"},g={class:"nav"},w=["to"],C={class:"ml-[10px]"},N={class:"menu"},B={class:"ml-[6px] line-clamp-1"},E=f({__name:"content",props:{nav:{type:Array,default:()=>[]},menu:{type:Array,default:()=>[]}},setup(n){return(I,i)=>{const u=_;return r(),e("div",y,[p(u,null,{default:a(()=>[t("div",k,[t("div",b,[t("div",g,[(r(!0),e(m,null,c(n.nav,(o,s)=>(r(),e(m,{key:s},[o.is_show=="1"?(r(),e("div",{key:0,to:o.link.path,class:h(["nav-item",{active:s==0}])},[p(l,{width:"18px",height:"18px",src:s==0?o.selected:o.unselected,fit:"cover"},{error:a(()=>[...i[0]||(i[0]=[t("span",null,null,-1)])]),_:1},8,["src"]),t("div",C,d(o.name),1)],10,w)):v("",!0)],64))),128))])]),t("div",null,[t("div",N,[(r(!0),e(m,null,c(n.menu,(o,s)=>(r(),e("div",{class:"menu-item",key:s},[p(l,{width:"16px",height:"16px",src:o.unselected,fit:"cover"},{error:a(()=>[...i[1]||(i[1]=[t("span",null,null,-1)])]),_:1},8,["src"]),t("span",B,d(o.name),1)]))),128))])])])]),_:1})])}}}),ct=x(E,[["__scopeId","data-v-35c14957"]]);export{ct as default};
@@ -1 +1 @@
import{b as y,d as v}from"./index-DgHUF7DW.js";import d from"./decoration-img-CttNGVCW.js";import{f as b,ak as t,I as e,J as i,H as m,F as x,ap as f,a as n,A as g}from"./@vue/runtime-core-D7eUgySO.js";import{Q as c}from"./@vue/shared-C75lBtbe.js";import{y as u}from"./@vue/reactivity-maRK_BBd.js";import"./nprogress-BpICrWuH.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./element-plus-D-JFNXWu.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./@element-plus/icons-vue-Blep2MBz.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const k={class:"my-service"},w={key:0,class:"title px-[15px] py-[10px]"},B={key:1,class:"flex flex-wrap pt-[20px] pb-[10px]"},I={class:"mt-[7px]"},N={key:2},V={class:"ml-[10px] flex-1"},j=b({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(o){const _=o,a=g(()=>{var s;return((s=_.content.data)==null?void 0:s.filter(l=>l.is_show=="1"))||[]});return(s,l)=>{const h=y;return t(),e("div",k,[o.content.title?(t(),e("div",w,[i("div",null,c(o.content.title),1)])):m("",!0),o.content.style==1?(t(),e("div",B,[(t(!0),e(x,null,f(u(a),(r,p)=>(t(),e("div",{key:p,class:"flex flex-col items-center w-1/4 mb-[15px]"},[n(d,{width:"26px",height:"26px",src:r.image,alt:""},null,8,["src"]),i("div",I,c(r.name),1)]))),128))])):m("",!0),o.content.style==2?(t(),e("div",N,[(t(!0),e(x,null,f(u(a),(r,p)=>(t(),e("div",{key:p,class:"flex items-center border-b border-[#e5e5e5] h-[50px] px-[12px]"},[n(d,{width:"24px",height:"24px",src:r.image,alt:""},null,8,["src"]),i("div",V,c(r.name),1),i("div",null,[n(h,{name:"el-icon-ArrowRight"})])]))),128))])):m("",!0)])}}}),lt=v(j,[["__scopeId","data-v-2f09c27b"]]);export{lt as default}; import{b as y,d as v}from"./index-B-xN0T_Y.js";import d from"./decoration-img-CC8K0JZ3.js";import{f as b,ak as t,I as e,J as i,H as m,F as x,ap as f,a as n,A as g}from"./@vue/runtime-core-D7eUgySO.js";import{Q as c}from"./@vue/shared-C75lBtbe.js";import{y as u}from"./@vue/reactivity-maRK_BBd.js";import"./nprogress-BpICrWuH.js";import"./vue-router-CJXI7XhX.js";import"./pinia-BhomUS5m.js";import"./axios-C80V62Fs.js";import"./lodash-Ct9_CZb9.js";import"./element-plus-CW0okzRn.js";import"./@vue/runtime-dom-DVgibYoU.js";import"./@element-plus/icons-vue-DBw-wZMr.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-BOuxpn4j.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-DCeljLnb.js";import"./@vueuse/shared-B444yVpD.js";import"./css-color-function-BVb6B1lA.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-ChYu0NfX.js";import"./clipboard-Bmfw2kIN.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-jaPyNblr.js";import"./@highlightjs/vue-plugin-ASXrwou_.js";const k={class:"my-service"},w={key:0,class:"title px-[15px] py-[10px]"},B={key:1,class:"flex flex-wrap pt-[20px] pb-[10px]"},I={class:"mt-[7px]"},N={key:2},V={class:"ml-[10px] flex-1"},j=b({__name:"content",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},setup(o){const _=o,a=g(()=>{var s;return((s=_.content.data)==null?void 0:s.filter(l=>l.is_show=="1"))||[]});return(s,l)=>{const h=y;return t(),e("div",k,[o.content.title?(t(),e("div",w,[i("div",null,c(o.content.title),1)])):m("",!0),o.content.style==1?(t(),e("div",B,[(t(!0),e(x,null,f(u(a),(r,p)=>(t(),e("div",{key:p,class:"flex flex-col items-center w-1/4 mb-[15px]"},[n(d,{width:"26px",height:"26px",src:r.image,alt:""},null,8,["src"]),i("div",I,c(r.name),1)]))),128))])):m("",!0),o.content.style==2?(t(),e("div",N,[(t(!0),e(x,null,f(u(a),(r,p)=>(t(),e("div",{key:p,class:"flex items-center border-b border-[#e5e5e5] h-[50px] px-[12px]"},[n(d,{width:"24px",height:"24px",src:r.image,alt:""},null,8,["src"]),i("div",V,c(r.name),1),i("div",null,[n(h,{name:"el-icon-ArrowRight"})])]))),128))])):m("",!0)])}}}),lt=v(j,[["__scopeId","data-v-2f09c27b"]]);export{lt as default};

Some files were not shown because too many files have changed in this diff Show More