1. 更新切换账号逻辑

2. 诊所管理员功能上线
This commit is contained in:
李琦
2026-05-30 16:36:33 +08:00
parent 27202c0740
commit 31551437c2
16 changed files with 1820 additions and 792 deletions

File diff suppressed because one or more lines are too long

View File

@@ -28,6 +28,7 @@
<!-- 操作面板通栏 -->
<view class="setting-panel">
<account-switch-entry />
<view
class="setting-item action-item"
hover-class="item-hover"
@@ -46,9 +47,10 @@
<script>
import ClinicPageLayout from '../components/clinic-page-layout.vue'
import AccountSwitchEntry from '@/components/account-switch/account-switch-entry.vue'
export default {
components: { ClinicPageLayout },
components: { ClinicPageLayout, AccountSwitchEntry },
data() {
return {
displayName: '',

View File

@@ -1,135 +1,316 @@
<template>
<clinic-page-layout title="药品详情" :show-back="true">
<view v-if="info.id" class="card">
<image class="hero" :src="display.imageUrl" mode="aspectFit" />
<view class="row"><text>药品名称</text><text>{{ display.drugName }}</text></view>
<view class="row"><text>拼音</text><text>{{ display.pinyin }}</text></view>
<view class="row"><text>供货价</text><text>{{ display.buyPrice }}</text></view>
<view class="row"><text>建议售价</text><text>{{ display.suggestPrice }}</text></view>
<view class="row"><text>售价</text><text>{{ display.price }}</text></view>
<view class="row"><text>库存</text><text>{{ display.stock }}</text></view>
<view class="row"><text>状态</text><text>{{ display.statusText }}</text></view>
</view>
<clinic-page-layout title="药品详情" :show-back="true">
<view v-if="info.id" class="page-container">
<!-- 头部信息卡片 -->
<view class="card hero-card">
<view class="image-wrapper">
<image class="hero" :src="display.imageUrl" mode="aspectFill" />
</view>
<view class="main-info">
<text class="drug-name">{{ display.drugName }}</text>
<text class="pinyin">拼音: {{ display.pinyin_simple || '--' }}</text>
</view>
</view>
<view v-if="info.id" class="btn-group">
<button class="btn secondary" @click="openPriceEdit">修改售价</button>
<button class="btn primary" @click="toggleStatus">
{{ display.isOnShelf ? '下架' : '上架' }}
</button>
</view>
<!-- 核心数据卡片 -->
<view class="card data-card">
<view class="row">
<text class="label">状态</text>
<view class="status-tag" :class="display.isOnShelf ? 'tag-on' : 'tag-off'">
{{ display.statusText }}
</view>
</view>
<view class="row">
<text class="label">库存</text>
<text class="value stock-value">{{ display.stock }}</text>
</view>
<price-edit-modal
:visible="priceModalVisible"
:item="info.id ? info : null"
@close="closePriceEdit"
@confirm="onPriceConfirm"
/>
</clinic-page-layout>
<view class="divider"></view>
<view class="row">
<text class="label">供货价</text>
<text class="value">{{ display.buyPrice }}</text>
</view>
<view class="row">
<text class="label">建议售价</text>
<text class="value">{{ display.suggestPrice }}</text>
</view>
<view class="row highlight-row">
<text class="label">当前售价</text>
<text class="value price-large">{{ display.price }}</text>
</view>
</view>
<!-- 底部操作按钮组 -->
<view v-if="info.id" class="action-group">
<view class="btn-large btn-outline" hover-class="btn-hover-opacity" @click="openPriceEdit">
修改售价
</view>
<view
class="btn-large"
:class="display.isOnShelf ? 'btn-danger' : 'btn-primary'"
hover-class="btn-hover-opacity"
@click="toggleStatus"
>
{{ display.isOnShelf ? '下架该药品' : '上架该药品' }}
</view>
</view>
</view>
<price-edit-modal
:visible="priceModalVisible"
:item="info.id ? info : null"
@close="closePriceEdit"
@confirm="onPriceConfirm"
/>
</clinic-page-layout>
</template>
<script>
import ClinicPageLayout from '../components/clinic-page-layout.vue'
import PriceEditModal from './components/PriceEditModal.vue'
import {
getWarehouseDetail,
updateWarehouseStatus,
updateWarehousePrice,
} from '@/api/clinicAdmin.js'
import { mapWarehouseRow } from '../common/display.js'
import ClinicPageLayout from '../components/clinic-page-layout.vue'
import PriceEditModal from './components/PriceEditModal.vue'
import {
getWarehouseDetail,
updateWarehouseStatus,
updateWarehousePrice,
} from '@/api/clinicAdmin.js'
import { mapWarehouseRow } from '../common/display.js'
export default {
components: { ClinicPageLayout, PriceEditModal },
data() {
return {
id: 0,
info: {},
priceModalVisible: false,
priceSubmitting: false,
}
},
computed: {
display() {
return mapWarehouseRow(this.info)
},
},
onLoad(q) {
this.id = Number(q.id || 0)
this.load()
},
methods: {
load() {
getWarehouseDetail(this.id).then(w => {
if (w.ok) this.info = w.data || {}
})
},
openPriceEdit() {
this.priceModalVisible = true
},
closePriceEdit() {
this.priceModalVisible = false
},
onPriceConfirm(price) {
if (this.priceSubmitting) return
this.priceSubmitting = true
updateWarehousePrice({ id: this.id, price }).then(w => {
if (w.ok) {
uni.showToast({ title: '修改成功' })
this.closePriceEdit()
this.load()
}
}).finally(() => { this.priceSubmitting = false })
},
toggleStatus() {
updateWarehouseStatus(this.id).then(w => {
if (w.ok) {
uni.showToast({ title: '操作成功' })
this.load()
}
})
},
},
}
export default {
components: { ClinicPageLayout, PriceEditModal },
data() {
return {
id: 0,
info: {},
priceModalVisible: false,
priceSubmitting: false,
}
},
computed: {
display() {
return mapWarehouseRow(this.info)
},
},
onLoad(q) {
this.id = Number(q.id || 0)
this.load()
},
methods: {
load() {
getWarehouseDetail(this.id).then(w => {
if (w.ok) this.info = w.data || {}
})
},
openPriceEdit() {
this.priceModalVisible = true
},
closePriceEdit() {
this.priceModalVisible = false
},
onPriceConfirm(price) {
if (this.priceSubmitting) return
this.priceSubmitting = true
updateWarehousePrice({ id: this.id, price }).then(w => {
if (w.ok) {
uni.showToast({ title: '修改成功' })
this.closePriceEdit()
this.load()
}
}).finally(() => { this.priceSubmitting = false })
},
toggleStatus() {
updateWarehouseStatus(this.id).then(w => {
if (w.ok) {
uni.showToast({ title: '操作成功' })
this.load()
}
})
},
},
}
</script>
<style lang="scss" scoped>
/* 同步了列表页的核心色板 */
$theme-color: #6acdbb;
$theme-color-light: rgba(106, 205, 187, 0.12);
$text-primary: #2c3e50;
$text-secondary: #8a97a3;
$text-light: #b0b8c1;
$bg-color: #f7f9fa;
$border-color: #ebedf0;
$danger-color: #ff6b6b;
$danger-color-light: rgba(255, 107, 107, 0.1);
.page-container {
padding: 24rpx;
padding-bottom: 60rpx;
}
.card {
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 32rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
background: #ffffff;
border-radius: 24rpx;
padding: 32rpx;
margin-bottom: 24rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.03);
}
/* 头部卡片特异样式 */
.hero-card {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 40rpx;
}
.image-wrapper {
width: 100%;
border-radius: 16rpx;
overflow: hidden;
background: $bg-color;
border: 1rpx solid $border-color;
margin-bottom: 32rpx;
}
.hero {
width: 100%;
height: 360rpx;
margin-bottom: 24rpx;
border-radius: 12rpx;
background: #f8f8f8;
width: 100%;
height: 400rpx;
display: block;
}
.main-info {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.drug-name {
font-size: 36rpx;
font-weight: 600;
color: $text-primary;
margin-bottom: 12rpx;
line-height: 1.4;
}
.pinyin {
font-size: 26rpx;
color: $text-secondary;
}
/* 核心数据卡片样式 */
.data-card {
padding: 16rpx 32rpx;
}
.row {
display: flex;
justify-content: space-between;
padding: 16rpx 0;
font-size: 28rpx;
border-bottom: 1rpx solid #f0f0f0;
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 0;
}
.btn-group {
display: flex;
flex-direction: column;
gap: 24rpx;
.divider {
height: 1rpx;
background-color: $border-color;
margin: 8rpx 0;
}
.btn {
border-radius: 44rpx;
font-size: 30rpx;
margin: 0;
.label {
font-size: 28rpx;
color: $text-secondary;
}
.btn.primary {
background: #6acdbb;
color: #fff;
.value {
font-size: 28rpx;
color: $text-primary;
font-weight: 500;
}
.btn.secondary {
background: #fff;
color: #6acdbb;
border: 1rpx solid #6acdbb;
.stock-value {
font-family: monospace; /* 数字更清晰 */
font-size: 30rpx;
}
</style>
.highlight-row {
margin-top: 8rpx;
background: #fafbfa; /* 极浅的背景强调 */
margin: 0 -32rpx;
padding: 32rpx;
border-bottom-left-radius: 24rpx;
border-bottom-right-radius: 24rpx;
}
.highlight-row .label {
color: $text-primary;
font-weight: 500;
}
.price-large {
font-size: 40rpx;
color: $theme-color;
font-weight: 600;
}
/* 标签样式 */
.status-tag {
font-size: 24rpx;
font-weight: 500;
padding: 6rpx 20rpx;
border-radius: 12rpx;
}
.tag-on {
color: $theme-color;
background: $theme-color-light;
}
.tag-off {
color: $text-secondary;
background: $bg-color;
}
/* 底部操作按钮组 */
.action-group {
display: flex;
flex-direction: column;
gap: 24rpx;
margin-top: 16rpx;
}
.btn-large {
width: 100%;
height: 96rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 48rpx;
font-size: 32rpx;
font-weight: 500;
transition: opacity 0.2s;
box-sizing: border-box;
}
.btn-primary {
background: $theme-color;
color: #ffffff;
box-shadow: 0 8rpx 24rpx $theme-color-light;
}
.btn-danger {
background: $danger-color;
color: #ffffff;
box-shadow: 0 8rpx 24rpx $danger-color-light;
}
.btn-outline {
background: #ffffff;
color: $theme-color;
border: 2rpx solid $theme-color;
}
.btn-hover-opacity {
opacity: 0.7;
}
</style>

View File

@@ -1,231 +1,383 @@
<template>
<clinic-page-layout :title="pageTitle" :show-back="true">
<view class="search">
<input v-model="keyword" placeholder="搜索药品名称" @confirm="reload" />
<text @click="reload">搜索</text>
</view>
<clinic-page-layout :title="pageTitle" :show-back="true">
<!-- 搜索栏优化胶囊式设计增加视觉呼吸感 -->
<view class="search-wrapper">
<view class="search-bar">
<input class="search-input" v-model="keyword" placeholder="搜索药品名称" placeholder-class="search-placeholder" @confirm="reload" />
<view class="search-btn" hover-class="btn-hover" @click="reload">搜索</view>
</view>
</view>
<view
v-for="item in list"
:key="item._wxKey"
class="item"
@click="goDetail(item)"
>
<image class="thumb" :src="rowDisplay(item).imageUrl" mode="aspectFill" />
<view class="body">
<view class="title">{{ rowDisplay(item).drugName }}</view>
<view class="sub">供货 {{ rowDisplay(item).buyPrice }} · 售价 {{ rowDisplay(item).price }}</view>
<view class="sub">库存 {{ rowDisplay(item).stock }}</view>
</view>
<view class="actions" @click.stop>
<view class="tag" :class="rowDisplay(item).isOnShelf ? 'on' : 'off'">{{ rowDisplay(item).statusText }}</view>
<view class="btn-row">
<text class="act-btn" @click="openPriceEdit(item)">改价</text>
<text class="act-btn shelf" @click="toggleStatus(item)">
{{ rowDisplay(item).isOnShelf ? '下架' : '上架' }}
</text>
</view>
</view>
</view>
<view class="list-container">
<view
v-for="item in list"
:key="item._wxKey"
class="item-card"
hover-class="card-hover"
@click="goDetail(item)"
>
<!-- 左侧缩略图 -->
<image class="thumb" :src="rowDisplay(item).imageUrl" mode="aspectFill" />
<view v-if="!loading && !list.length" class="empty">暂无药品</view>
<!-- 右侧内容区 -->
<view class="content">
<!-- 顶部标题与状态标签对齐 -->
<view class="header-row">
<text class="title">{{ rowDisplay(item).drugName }}</text>
<view class="status-tag" :class="rowDisplay(item).isOnShelf ? 'tag-on' : 'tag-off'">
{{ rowDisplay(item).statusText }}
</view>
</view>
<price-edit-modal
:visible="priceModalVisible"
:item="priceEditItem"
@close="closePriceEdit"
@confirm="onPriceConfirm"
/>
</clinic-page-layout>
<!-- 中部详细信息 -->
<view class="info-group">
<text class="info-text">供货 {{ rowDisplay(item).buyPrice }} · 售价 {{ rowDisplay(item).price }}</text>
<text class="info-text">库存 {{ rowDisplay(item).stock }}</text>
</view>
<!-- 底部操作按钮横向排列增加点击区域与反馈 -->
<view class="action-row" @click.stop>
<view class="action-btn outline" hover-class="btn-hover-opacity" @click.stop="openPriceEdit(item)">
改价
</view>
<view class="action-btn" :class="rowDisplay(item).isOnShelf ? 'btn-danger' : 'btn-primary'" hover-class="btn-hover-opacity" @click.stop="toggleStatus(item)">
{{ rowDisplay(item).isOnShelf ? '下架' : '上架' }}
</view>
</view>
</view>
</view>
</view>
<!-- 空状态优化 -->
<view v-if="!loading && !list.length" class="empty-state">
<view class="empty-icon"></view>
<text class="empty-text">暂无药品数据</text>
</view>
<price-edit-modal
:visible="priceModalVisible"
:item="priceEditItem"
@close="closePriceEdit"
@confirm="onPriceConfirm"
/>
</clinic-page-layout>
</template>
<script>
import ClinicPageLayout from '../components/clinic-page-layout.vue'
import PriceEditModal from './components/PriceEditModal.vue'
import {
getWarehouseList,
updateWarehouseStatus,
updateWarehousePrice,
} from '@/api/clinicAdmin.js'
import { withWxKey } from '@/utils/wxListKey.js'
import { mapWarehouseRow } from '../common/display.js'
import ClinicPageLayout from '../components/clinic-page-layout.vue'
import PriceEditModal from './components/PriceEditModal.vue'
import {
getWarehouseList,
updateWarehouseStatus,
updateWarehousePrice,
} from '@/api/clinicAdmin.js'
import { withWxKey } from '@/utils/wxListKey.js'
import { mapWarehouseRow } from '../common/display.js'
export default {
components: { ClinicPageLayout, PriceEditModal },
data() {
return {
pageTitle: '仓库管理',
warehouseType: '',
keyword: '',
list: [],
page: 1,
loading: false,
priceModalVisible: false,
priceEditItem: null,
priceSubmitting: false,
}
},
onLoad(q) {
if (q.label) {
this.pageTitle = decodeURIComponent(q.label)
}
if (q.type != null && q.type !== '') {
this.warehouseType = q.type
}
this.reload()
},
onReachBottom() {
this.load(this.page + 1, true)
},
methods: {
rowDisplay(item) {
return mapWarehouseRow(item)
},
reload() {
this.page = 1
this.load(1, false)
},
load(page, append) {
this.loading = true
const params = { page, pageSize: 20 }
if (this.keyword) params.name = this.keyword
if (this.warehouseType !== '' && this.warehouseType != null) {
params.type = this.warehouseType
}
getWarehouseList(params).then(w => {
const items = withWxKey((w.data && w.data.items) || [], 'id', 'wh')
this.list = append ? this.list.concat(items) : items
this.page = page
}).finally(() => { this.loading = false })
},
goDetail(item) {
uni.navigateTo({ url: '/subPackages/sub_clinic_admin/warehouse/detail?id=' + item.id })
},
openPriceEdit(item) {
this.priceEditItem = item
this.priceModalVisible = true
},
closePriceEdit() {
this.priceModalVisible = false
this.priceEditItem = null
},
onPriceConfirm(price) {
if (!this.priceEditItem || this.priceSubmitting) return
this.priceSubmitting = true
updateWarehousePrice({ id: this.priceEditItem.id, price }).then(w => {
if (w.ok) {
uni.showToast({ title: '修改成功' })
this.closePriceEdit()
this.reload()
}
}).finally(() => { this.priceSubmitting = false })
},
toggleStatus(item) {
const action = item.status === 2 ? '下架' : '上架'
uni.showModal({
title: '提示',
content: '确定' + action + '「' + ((item.drug && item.drug.drug_name) || '') + '」?',
success: (res) => {
if (!res.confirm) return
updateWarehouseStatus(item.id).then(w => {
if (w.ok) {
uni.showToast({ title: '操作成功' })
item.status = item.status === 2 ? 1 : 2
}
})
},
})
},
},
}
export default {
components: { ClinicPageLayout, PriceEditModal },
data() {
return {
pageTitle: '仓库管理',
warehouseType: '',
keyword: '',
list: [],
page: 1,
loading: false,
priceModalVisible: false,
priceEditItem: null,
priceSubmitting: false,
}
},
onLoad(q) {
if (q.label) {
this.pageTitle = decodeURIComponent(q.label)
}
if (q.type != null && q.type !== '') {
this.warehouseType = q.type
}
this.reload()
},
onReachBottom() {
this.load(this.page + 1, true)
},
methods: {
rowDisplay(item) {
return mapWarehouseRow(item)
},
reload() {
this.page = 1
this.load(1, false)
},
load(page, append) {
this.loading = true
const params = { page, pageSize: 20 }
if (this.keyword) params.name = this.keyword
if (this.warehouseType !== '' && this.warehouseType != null) {
params.type = this.warehouseType
}
getWarehouseList(params).then(w => {
const items = withWxKey((w.data && w.data.items) || [], 'id', 'wh')
this.list = append ? this.list.concat(items) : items
this.page = page
}).finally(() => { this.loading = false })
},
goDetail(item) {
uni.navigateTo({ url: '/subPackages/sub_clinic_admin/warehouse/detail?id=' + item.id })
},
openPriceEdit(item) {
this.priceEditItem = item
this.priceModalVisible = true
},
closePriceEdit() {
this.priceModalVisible = false
this.priceEditItem = null
},
onPriceConfirm(price) {
if (!this.priceEditItem || this.priceSubmitting) return
this.priceSubmitting = true
updateWarehousePrice({ id: this.priceEditItem.id, price }).then(w => {
if (w.ok) {
uni.showToast({ title: '修改成功' })
this.closePriceEdit()
this.reload()
}
}).finally(() => { this.priceSubmitting = false })
},
toggleStatus(item) {
const action = item.status === 2 ? '下架' : '上架'
uni.showModal({
title: '提示',
content: '确定' + action + '「' + ((item.drug && item.drug.drug_name) || '') + '」?',
success: (res) => {
if (!res.confirm) return
updateWarehouseStatus(item.id).then(w => {
if (w.ok) {
uni.showToast({ title: '操作成功' })
item.status = item.status === 2 ? 1 : 2
}
})
},
})
},
},
}
</script>
<style lang="scss" scoped>
.search {
display: flex;
background: #fff;
padding: 16rpx 24rpx;
border-radius: 16rpx;
margin-bottom: 24rpx;
align-items: center;
/* 核心主题色变量提取,方便后续统一管理 */
$theme-color: #6acdbb;
$theme-color-light: rgba(106, 205, 187, 0.12);
$text-primary: #2c3e50;
$text-secondary: #8a97a3;
$text-light: #b0b8c1;
$bg-color: #f7f9fa;
$border-color: #ebedf0;
$danger-color: #ff6b6b;
$danger-color-light: rgba(255, 107, 107, 0.1);
.search-wrapper {
padding: 16rpx 24rpx;
background-color: transparent;
position: sticky;
top: 0;
z-index: 10;
}
.search input {
flex: 1;
font-size: 28rpx;
.search-bar {
display: flex;
align-items: center;
background: #ffffff;
padding: 12rpx 16rpx 12rpx 32rpx;
border-radius: 40rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
}
.search text {
color: #6acdbb;
font-size: 28rpx;
margin-left: 16rpx;
.search-input {
flex: 1;
font-size: 28rpx;
color: $text-primary;
height: 60rpx;
}
.item {
display: flex;
align-items: flex-start;
background: #fff;
padding: 24rpx;
border-radius: 16rpx;
margin-bottom: 16rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
.search-placeholder {
color: $text-light;
}
.search-btn {
background: $theme-color;
color: #ffffff;
font-size: 26rpx;
font-weight: 500;
padding: 12rpx 36rpx;
border-radius: 30rpx;
margin-left: 16rpx;
transition: all 0.2s;
}
.list-container {
padding: 0 24rpx 24rpx;
}
.item-card {
display: flex;
background: #ffffff;
padding: 24rpx;
border-radius: 24rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.03);
transition: transform 0.2s, box-shadow 0.2s;
}
.card-hover {
transform: scale(0.99);
background-color: #fafafa;
}
.thumb {
width: 100rpx;
height: 100rpx;
border-radius: 12rpx;
flex-shrink: 0;
background: #f5f5f5;
width: 140rpx;
height: 140rpx;
border-radius: 16rpx;
flex-shrink: 0;
background: $bg-color;
border: 1rpx solid $border-color;
}
.body {
flex: 1;
margin-left: 20rpx;
min-width: 0;
padding-right: 12rpx;
.content {
flex: 1;
margin-left: 24rpx;
min-width: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.header-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 8rpx;
}
.title {
font-size: 28rpx;
color: #333;
font-size: 30rpx;
color: $text-primary;
font-weight: 600;
line-height: 1.4;
flex: 1;
margin-right: 16rpx;
/* 单行截断 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sub {
font-size: 24rpx;
color: #999;
margin-top: 8rpx;
.status-tag {
font-size: 20rpx;
font-weight: 500;
padding: 4rpx 14rpx;
border-radius: 8rpx;
flex-shrink: 0;
line-height: 1.5;
}
.actions {
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 12rpx;
.tag-on {
color: $theme-color;
background: $theme-color-light;
}
.tag {
font-size: 22rpx;
padding: 4rpx 12rpx;
border-radius: 8rpx;
.tag-off {
color: $text-secondary;
background: $bg-color;
}
.tag.on {
color: #6acdbb;
background: rgba(106, 205, 187, 0.12);
.info-group {
display: flex;
flex-direction: column;
gap: 6rpx;
margin-bottom: 16rpx;
}
.tag.off {
color: #999;
background: #f5f5f5;
.info-text {
font-size: 24rpx;
color: $text-secondary;
}
.btn-row {
display: flex;
flex-direction: column;
gap: 8rpx;
align-items: flex-end;
.action-row {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 16rpx;
margin-top: auto;
}
.act-btn {
font-size: 24rpx;
color: #6acdbb;
padding: 4rpx 0;
.action-btn {
font-size: 24rpx;
padding: 10rpx 28rpx;
border-radius: 12rpx;
font-weight: 500;
line-height: 1.5;
transition: opacity 0.2s;
}
.act-btn.shelf {
color: #666;
.action-btn.outline {
color: $text-primary;
background: #ffffff;
border: 1rpx solid $border-color;
}
.empty {
text-align: center;
color: #999;
padding: 60rpx;
.action-btn.btn-primary {
color: #ffffff;
background: $theme-color;
border: 1rpx solid $theme-color;
}
</style>
.action-btn.btn-danger {
color: $danger-color;
background: $danger-color-light;
border: 1rpx solid transparent;
}
.btn-hover {
opacity: 0.8;
}
.btn-hover-opacity {
opacity: 0.6;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 0;
}
.empty-icon {
width: 200rpx;
height: 200rpx;
background-color: $bg-color;
border-radius: 50%;
margin-bottom: 30rpx;
position: relative;
}
/* 用伪元素做一个简单的空状态图形占位有条件可替换为真实的Image/SVG */
.empty-icon::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80rpx;
height: 80rpx;
border: 8rpx solid $border-color;
border-radius: 16rpx;
}
.empty-text {
color: $text-light;
font-size: 28rpx;
}
</style>

View File

@@ -36,6 +36,10 @@
</view> -->
</view>
<view class="p-row-32 m-t-8 white b-r-8">
<account-switch-entry />
</view>
<view class="p-row-32 m-t-8" style="height: 100rpx;">
<u-button :throttle-time="0" shape="circle" :custom-style="{backgroundColor:'#6ACDBB',color:'#fff',heigth:'96rpx'}" @click="logout">
退出登录</u-button>
@@ -49,8 +53,10 @@
logout,
toUpload,
} from '@/api/all.js'
import AccountSwitchEntry from '@/components/account-switch/account-switch-entry.vue'
import { chooseAvatarImage } from '@/common/js/select-avatar-image.js';
export default {
components: { AccountSwitchEntry },
data() {
return {
doctorInfo: []

View File

@@ -22,6 +22,9 @@
40056256325
</view>
</view>
<view class="p-row-32 m-t-8 white">
<account-switch-entry />
</view>
<view class="p-row-32 m-t-8" style="height: 80rpx;">
<u-button :throttle-time="0" shape="circle" :custom-style="{backgroundColor:'#6ACDBB',color:'#fff',heigth:'86rpx'}" @click="logout">
退出登录</u-button>
@@ -33,7 +36,9 @@
import {
logout
} from '@/api/all.js'
import AccountSwitchEntry from '@/components/account-switch/account-switch-entry.vue'
export default {
components: { AccountSwitchEntry },
data() {
return {}
},