1. 诊所管理

This commit is contained in:
李琦
2026-06-18 10:52:42 +08:00
parent 73d535378e
commit 66a2243042
8 changed files with 558 additions and 472 deletions

View File

@@ -1,8 +1,11 @@
<template> <template>
<business-page-layout title="商品订单" :show-back="true"> <business-page-layout title="商品订单" :show-back="true">
<view class="order-list-container"> <view class="order-list-container">
<!-- 顶部筛选 -->
<page-sticky-header> <!-- 终极修复弃用会导致冲突的 page-sticky-header -->
<!-- 改用原生 native-sticky-header绑定动态计算的导航栏高度精准吸附在 u-navbar 下方 -->
<view class="native-sticky-header" :style="{ top: navTopOffset + 'px' }">
<view class="header-solid-bg">
<view class="quick-filter"> <view class="quick-filter">
<view class="filter-row date-row"> <view class="filter-row date-row">
<picker mode="date" :value="dateStart" @change="onStart"> <picker mode="date" :value="dateStart" @change="onStart">
@@ -12,9 +15,10 @@
<picker mode="date" :value="dateEnd" @change="onEnd"> <picker mode="date" :value="dateEnd" @change="onEnd">
<view class="filter-picker date-picker">{{ dateEnd || '结束日期' }}</view> <view class="filter-picker date-picker">{{ dateEnd || '结束日期' }}</view>
</picker> </picker>
<view class="btn-query" @click="reload">查询</view>
</view> </view>
<view class="filter-query-btn" @click="reload">查询</view>
</view> </view>
<collapsible-filter-panel title="订单筛选" @clear="resetFilter"> <collapsible-filter-panel title="订单筛选" @clear="resetFilter">
<view class="filter-row"> <view class="filter-row">
<text class="filter-label">订单号</text> <text class="filter-label">订单号</text>
@@ -39,7 +43,8 @@
</picker> </picker>
</view> </view>
</collapsible-filter-panel> </collapsible-filter-panel>
</page-sticky-header> </view>
</view>
<!-- 统计卡片区 --> <!-- 统计卡片区 -->
<scroll-view v-if="statItems.length" class="stats-scroll" scroll-x> <scroll-view v-if="statItems.length" class="stats-scroll" scroll-x>
@@ -61,63 +66,62 @@
:hover-stay-time="150" :hover-stay-time="150"
@click="goDetail(item)" @click="goDetail(item)"
> >
<!-- 顶部单号与状态 --> <!-- 顶部业务归属与状态 -->
<view class="card-head"> <view class="card-header">
<view class="order-id"> <view class="header-left">
<text class="id-icon"></text> <!-- 诊所信息提权放在最醒目的左上角 -->
<text class="id-text">{{ rowDisplay(item).orderNo }}</text> <view class="clinic-tag" v-if="rowDisplay(item).storeName !== '-'">
<text class="clinic-name">{{ rowDisplay(item).storeName }}</text>
</view> </view>
<view <view class="order-no-wrap">
class="status-badge" <text class="lbl">单号</text>
:class="['status-' + (rowDisplay(item).status || 'default')]" <text class="val">{{ rowDisplay(item).orderNo }}</text>
> </view>
</view>
<view class="status-text" :class="['status-' + (rowDisplay(item).status || 'default')]">
{{ rowDisplay(item).statusText }} {{ rowDisplay(item).statusText }}
</view> </view>
</view> </view>
<!-- 核心商品与收件信息无边框内联排版节省大量高度 -->
<view class="card-body"> <view class="card-body">
<!-- 核心视觉区商品与金额 --> <!-- 药品名称与标签同行排版 -->
<view class="main-info"> <view class="product-row">
<view class="title-wrap"> <text class="product-name">{{ rowDisplay(item).productSummary || '药品订单' }}</text>
<text class="goods-title">{{ rowDisplay(item).productSummary || '药品订单' }}</text> </view>
<view class="goods-tags"> <view class="tags-row">
<text class="modern-tag tag-type">{{ rowDisplay(item).prescriptionTypeText }}</text> <text class="modern-tag tag-type">{{ rowDisplay(item).prescriptionTypeText }}</text>
<text class="modern-tag tag-delivery">{{ rowDisplay(item).deliveryText }}</text> <text class="modern-tag tag-delivery">{{ rowDisplay(item).deliveryText }}</text>
</view> </view>
<!-- 去掉臃肿的灰色岛采用精致的文本网格 -->
<view class="info-grid">
<view class="info-item" v-if="rowDisplay(item).userNickname !== '-'">
<text class="info-lbl">就诊人</text>
<text class="info-val">{{ rowDisplay(item).userNickname }}</text>
</view> </view>
<view class="price-wrap"> <view class="info-item">
<text class="info-lbl">收件人</text>
<text class="info-val">
{{ rowDisplay(item).receiverName }}
<text class="info-sub" v-if="rowDisplay(item).receiverMobile">{{ rowDisplay(item).receiverMobile }}</text>
</text>
</view>
</view>
</view>
<!-- 底部时间价格与操作水平对齐 -->
<view class="card-footer">
<text class="time">{{ rowDisplay(item).createdAt }}</text>
<view class="footer-actions">
<view class="price-block">
<text class="price-lbl">实付</text>
<text class="currency">¥</text> <text class="currency">¥</text>
<text class="amount">{{ rowDisplay(item).totalPayPrice.replace('¥', '').trim() }}</text> <text class="amount">{{ rowDisplay(item).totalPayPrice.replace('¥', '').trim() }}</text>
</view> </view>
</view>
<!-- 信息岛 (Info Island)聚合次要信息的高级灰底区块 -->
<view class="info-island">
<view class="island-row" v-if="rowDisplay(item).userNickname !== '-'">
<text class="island-label">就诊人</text>
<text class="island-value">{{ rowDisplay(item).userNickname }}</text>
</view>
<view class="island-row">
<text class="island-label">收件人</text>
<text class="island-value">
{{ rowDisplay(item).receiverName }}
<text class="muted" v-if="rowDisplay(item).receiverMobile"> · {{ rowDisplay(item).receiverMobile }}</text>
</text>
</view>
<view class="island-row" v-if="rowDisplay(item).storeName !== '-'">
<text class="island-label">开方诊所</text>
<text class="island-value">{{ rowDisplay(item).storeName }}</text>
</view>
</view>
</view>
<!-- 底部时间与操作按键 -->
<view class="card-foot">
<text class="time">{{ rowDisplay(item).createdAt }}</text>
<view class="actions">
<view <view
v-if="rowDisplay(item).canViewPrescription" v-if="rowDisplay(item).canViewPrescription"
class="btn-ghost" class="btn-outline"
@click.stop="openPrescription(rowDisplay(item).pId)" @click.stop="openPrescription(rowDisplay(item).pId)"
> >
查看处方 查看处方
@@ -137,8 +141,8 @@
</template> </template>
<script> <script>
// 这里已经移除了引入产生冲突的 PageStickyHeader以保证代码的纯净性
import BusinessPageLayout from '@/subPackages/sub_business_shared/components/business-page-layout.vue' import BusinessPageLayout from '@/subPackages/sub_business_shared/components/business-page-layout.vue'
import PageStickyHeader from '@/subPackages/sub_business_shared/components/PageStickyHeader.vue'
import CollapsibleFilterPanel from '@/subPackages/sub_business_shared/components/CollapsibleFilterPanel.vue' import CollapsibleFilterPanel from '@/subPackages/sub_business_shared/components/CollapsibleFilterPanel.vue'
import PrescriptionDetailPopup from './components/PrescriptionDetailPopup.vue' import PrescriptionDetailPopup from './components/PrescriptionDetailPopup.vue'
import { withWxKey } from '@/utils/wxListKey.js' import { withWxKey } from '@/utils/wxListKey.js'
@@ -172,7 +176,7 @@ const PRESCRIPTION_TYPE_OPTIONS = [
export default { export default {
mixins: [businessMixin], mixins: [businessMixin],
components: { BusinessPageLayout, PageStickyHeader, CollapsibleFilterPanel, PrescriptionDetailPopup }, components: { BusinessPageLayout, CollapsibleFilterPanel, PrescriptionDetailPopup },
data() { data() {
return { return {
list: [], list: [],
@@ -186,6 +190,7 @@ export default {
dateStart: '', dateStart: '',
dateEnd: '', dateEnd: '',
statItems: [], statItems: [],
navTopOffset: 0, // 新增:用于存放导航栏计算后的确切高度
} }
}, },
computed: { computed: {
@@ -199,6 +204,14 @@ export default {
return PRESCRIPTION_TYPE_OPTIONS.map(o => o.label) return PRESCRIPTION_TYPE_OPTIONS.map(o => o.label)
}, },
}, },
created() {
// 动态计算顶部 u-navbar 的总高度 (状态栏 + navbar 固定 44px 高度)
// 这一步与 business-page-layout 内的计算逻辑保持完全一致,保证完美对接
const sys = uni.getSystemInfoSync()
const statusBarHeight = this.$statusBarHeight || sys.statusBarHeight || 0
const navbarHeight = this.$navbarHeight || 44
this.navTopOffset = statusBarHeight + navbarHeight
},
onLoad() { onLoad() {
this.applyOrderFilter(loadOrderFilter()) this.applyOrderFilter(loadOrderFilter())
this.bizApi.getOrderStatusOption().then(w => { this.bizApi.getOrderStatusOption().then(w => {
@@ -330,10 +343,11 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
$theme-primary: #6acdbb; $theme-primary: #6acdbb;
$color-bg-base: #F2F4F7; /* Apple 风格的冷调高级灰底色 */ $color-bg-base: #F2F4F7;
$color-text-main: #1D2129; $color-text-main: #1D2129;
$color-text-body: #4E5969; $color-text-body: #4E5969;
$color-text-muted: #86909C; $color-text-muted: #86909C;
$color-border: #E5E6EB;
.order-list-container { .order-list-container {
background-color: $color-bg-base; background-color: $color-bg-base;
@@ -341,271 +355,253 @@ $color-text-muted: #86909C;
padding-bottom: 60rpx; padding-bottom: 60rpx;
} }
/* 筛选区 */ /* ================= 核心:完美吸顶方案 ================= */
/* 原生 sticky 结合 Vue 计算出的精确导航栏高度(top),严丝合缝拦截在导航栏正下方 */
.native-sticky-header {
position: -webkit-sticky;
position: sticky;
z-index: 100; /* 高层级,保证滑动时覆盖在下方的卡片上 */
background-color: $color-bg-base; /* 必须有底色用于防穿透遮挡 */
}
.header-solid-bg {
/* 使用 padding 将内容向内挤,防止滑动过程的透明间隙穿透问题 */
padding: 16rpx 24rpx 16rpx;
}
/* 筛选项 UI 美化 */
.quick-filter { .quick-filter {
background: #fff; background: #fff;
padding: 24rpx; padding: 16rpx 20rpx;
margin-bottom: 16rpx; border-radius: 20rpx;
border-radius: 16rpx; box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
} }
.filter-row { .filter-row {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 16rpx; gap: 16rpx;
margin-bottom: 24rpx; margin-bottom: 24rpx;
&:last-child { margin-bottom: 0; }
}
.date-row {
margin-bottom: 0;
justify-content: space-between;
} }
.filter-label { .filter-label {
font-size: 28rpx; font-size: 28rpx;
color: $color-text-body; color: $color-text-body;
min-width: 140rpx; min-width: 130rpx;
} }
.filter-input, .filter-picker { .filter-input, .filter-picker {
flex: 1; flex: 1;
font-size: 28rpx; font-size: 26rpx;
padding: 16rpx 20rpx; padding: 14rpx 20rpx;
background: #F7F8FA; background: #F7F8FA;
border-radius: 12rpx; border-radius: 12rpx;
color: $color-text-main; color: $color-text-main;
} }
.date-row { flex-wrap: nowrap; }
.date-picker { text-align: center; } .date-picker { text-align: center; }
.sep { color: $color-text-muted; margin: 0 8rpx; font-size: 24rpx; } .sep { color: $color-text-muted; font-size: 24rpx; }
.filter-query-btn {
text-align: center; /* 重新设计的紧凑型查询按钮 */
padding: 24rpx; .btn-query {
flex-shrink: 0;
background: $theme-primary; background: $theme-primary;
color: #fff; color: #fff;
border-radius: 16rpx; padding: 0 32rpx;
font-size: 30rpx; height: 60rpx;
font-weight: 600; line-height: 60rpx;
margin-top: 32rpx; border-radius: 30rpx; /* 胶囊圆角 */
box-shadow: 0 8rpx 24rpx rgba(106, 205, 187, 0.2); font-size: 26rpx;
font-weight: 500;
box-shadow: 0 4rpx 12rpx rgba(106, 205, 187, 0.3);
transition: opacity 0.2s;
&:active { opacity: 0.8; }
} }
/* 统计卡片 */ /* 统计卡片 */
.stats-scroll { .stats-scroll { margin-bottom: 16rpx; white-space: nowrap; }
margin-bottom: 20rpx; .stats { display: inline-flex; gap: 20rpx; padding: 0 24rpx; }
white-space: nowrap;
}
.stats {
display: inline-flex;
gap: 20rpx;
padding: 16rpx 32rpx;
}
.stat-card { .stat-card {
display: inline-block; width: 300rpx;
width: 320rpx;
background: #fff; background: #fff;
padding: 32rpx; padding: 24rpx;
border-radius: 24rpx; border-radius: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02); box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.03);
vertical-align: top;
white-space: normal;
}
.stat-label {
display: block;
font-size: 26rpx;
color: $color-text-muted;
}
.stat-value {
display: block;
font-size: 42rpx;
color: $color-text-main;
font-weight: 700;
margin-top: 12rpx;
} }
.stat-label { display: block; font-size: 24rpx; color: $color-text-muted; }
.stat-value { display: block; font-size: 38rpx; color: $color-text-main; font-weight: 700; margin-top: 8rpx; }
/* ================= 核心高级卡片样式 ================= */ /* ================= 核心高级卡片样式 ================= */
.card-list-wrap { .card-list-wrap {
//padding: 0 24rpx; padding: 0 24rpx;
} }
.premium-card { .premium-card {
background: #ffffff; background: #ffffff;
border-radius: 32rpx; /* 超大圆角带来前沿视觉享受 */ border-radius: 24rpx;
margin-bottom: 24rpx; margin-bottom: 24rpx;
padding: 32rpx; padding: 28rpx;
border: 1rpx solid #E5E6EB; box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.015); /* 极其克制的阴影 */ border: 1px solid rgba(229, 230, 235, 0.5);
transition: all 0.2s ease;
} }
.card-hover { .card-hover {
transform: scale(0.98); transform: scale(0.99);
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.01);
background-color: #FAFAFA; background-color: #FAFAFA;
} }
/* 卡片头部 */ /* 卡片头部 */
.card-head { .card-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: flex-start;
margin-bottom: 28rpx; margin-bottom: 20rpx;
} }
.header-left {
.order-id { display: flex;
flex-direction: column;
gap: 8rpx;
}
.clinic-tag {
display: inline-flex;
}
.clinic-name {
font-size: 24rpx;
color: $color-text-main;
background: #F2F3F5;
padding: 4rpx 16rpx;
border-radius: 8rpx;
font-weight: 500;
}
.order-no-wrap {
font-size: 24rpx;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12rpx; gap: 12rpx;
} }
.order-no-wrap .lbl { color: $color-text-muted; }
.order-no-wrap .val { color: $color-text-body; font-family: monospace; letter-spacing: 0.5rpx;}
.id-icon { .status-text {
font-size: 20rpx;
color: #fff;
background-color: #C9CDD4;
padding: 4rpx 12rpx;
border-radius: 6rpx;
font-weight: 600;
}
.id-text {
font-size: 26rpx;
color: $color-text-muted;
font-family: SF Pro Text, monospace, sans-serif;
letter-spacing: 0.5rpx;
}
/* 状态标签配色优化 */
.status-badge {
font-size: 26rpx; font-size: 26rpx;
font-weight: 600; font-weight: 600;
color: $theme-primary; color: $theme-primary;
margin-top: 4rpx;
} }
/* 可根据实际的状态值(status)配置置灰 */
.status-done { color: $color-text-muted; font-weight: 400; } .status-done { color: $color-text-muted; font-weight: 400; }
.status-cancel { color: #F53F3F; } .status-cancel { color: #F53F3F; }
/* 核心内容区 */ /* 卡片主体 */
.card-body { .card-body {
margin-bottom: 24rpx; margin-bottom: 24rpx;
} }
.product-row {
.main-info { margin-bottom: 12rpx;
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 24rpx;
gap: 20rpx;
} }
.product-name {
.title-wrap { font-size: 30rpx; /* 适中的药品名称 */
flex: 1;
}
.goods-title {
font-size: 32rpx;
font-weight: 600; font-weight: 600;
color: $color-text-main; color: $color-text-main;
line-height: 1.4; line-height: 1.4;
margin-bottom: 16rpx;
/* 多行截断 */
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
} }
.tags-row {
.goods-tags {
display: flex; display: flex;
flex-wrap: wrap;
gap: 12rpx; gap: 12rpx;
margin-bottom: 20rpx;
} }
.modern-tag { .modern-tag {
font-size: 22rpx; font-size: 22rpx;
padding: 4rpx 14rpx; padding: 4rpx 12rpx;
border-radius: 8rpx; border-radius: 6rpx;
font-weight: 500; font-weight: 500;
} }
.tag-type { background: #FFF3E8; color: #FF7D00; } /* 柔和爱马仕橙 */ .tag-type { background: #FFF3E8; color: #FF7D00; }
.tag-delivery { background: #E8F3FF; color: #165DFF; } /* 科技蓝 */ .tag-delivery { background: #E8F3FF; color: #165DFF; }
.price-wrap { /* 雅致的信息网格排版 */
.info-grid {
display: flex; display: flex;
align-items: baseline; flex-direction: column;
color: $color-text-main; gap: 8rpx;
background: transparent; /* 去除灰底 */
} }
.info-item {
.currency {
font-size: 28rpx;
font-weight: 600;
margin-right: 4rpx;
}
.amount {
font-size: 44rpx;
font-weight: 700;
font-family: DIN Alternate, SF Pro Display, sans-serif;
}
/* 高级信息岛 (Inset Info Box) */
.info-island {
background-color: #F7F8FA;
border-radius: 16rpx;
padding: 24rpx;
}
.island-row {
display: flex; display: flex;
font-size: 24rpx; font-size: 26rpx;
line-height: 1.6; line-height: 1.5;
margin-bottom: 12rpx;
&:last-child {
margin-bottom: 0;
} }
.info-lbl {
.island-label {
color: $color-text-muted; color: $color-text-muted;
width: 110rpx; width: 110rpx;
flex-shrink: 0; flex-shrink: 0;
} }
.info-val {
.island-value {
color: $color-text-body; color: $color-text-body;
flex: 1; flex: 1;
word-break: break-all;
} }
.info-sub {
.muted {
color: $color-text-muted; color: $color-text-muted;
} margin-left: 12rpx;
font-size: 24rpx;
} }
/* 卡片底部 */ /* 卡片底部 */
.card-foot { .card-footer {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
border-top: 1rpx solid #F2F3F5; border-top: 1rpx dashed $color-border;
padding-top: 24rpx; padding-top: 24rpx;
} }
.time { .time {
font-size: 24rpx; font-size: 24rpx;
color: $color-text-muted; color: $color-text-muted;
} }
.footer-actions {
display: flex;
align-items: center;
gap: 24rpx;
}
.price-block {
display: flex;
align-items: baseline;
}
.price-lbl {
font-size: 22rpx;
color: $color-text-muted;
margin-right: 8rpx;
}
.currency {
font-size: 24rpx;
color: $color-text-main;
font-weight: 600;
}
.amount {
font-size: 36rpx;
font-weight: 700;
color: $color-text-main;
font-family: DIN Alternate, SF Pro Display, sans-serif;
}
.btn-ghost { /* 美化的边框按钮 */
.btn-outline {
font-size: 26rpx; font-size: 26rpx;
color: $theme-primary; color: $theme-primary;
background: rgba(106, 205, 187, 0.08); border: 1px solid $theme-primary;
padding: 10rpx 32rpx; padding: 8rpx 28rpx;
border-radius: 30rpx; border-radius: 30rpx;
font-weight: 500; font-weight: 500;
transition: background-color 0.2s; background: transparent;
transition: all 0.2s;
&:active { &:active {
background: rgba(106, 205, 187, 0.15); background: rgba(106, 205, 187, 0.08);
} }
} }
.empty-state { .empty-state { text-align: center; color: $color-text-muted; padding: 120rpx 0; font-size: 28rpx; }
text-align: center;
color: $color-text-muted;
padding: 120rpx 0;
font-size: 28rpx;
}
</style> </style>

View File

@@ -1,15 +1,15 @@
<template> <template>
<page-layout :is-platform="true" :title="title" :show-back="showBack" :show-tabbar="showTabbar" :tab-index="tabIndex"> <business-page-layout :title="title" :show-back="showBack" :show-tabbar="showTabbar" :tab-index="tabIndex">
<slot /> <slot />
</page-layout> </business-page-layout>
</template> </template>
<script> <script>
import PageLayout from '@/subPackages/sub_salesperson_manage/components/PageLayout.vue'; import BusinessPageLayout from '@/subPackages/sub_platform_admin/components/business-page-layout.vue';
export default { export default {
name: 'StorePageLayout', name: 'StorePageLayout',
components: { PageLayout }, components: { BusinessPageLayout },
props: { props: {
title: { type: String, default: '' }, title: { type: String, default: '' },
showBack: { type: Boolean, default: true }, showBack: { type: Boolean, default: true },

View File

@@ -139,7 +139,7 @@ export function createDefaultStoreInputForm() {
position: '', position: '',
province_id: null, province_id: null,
city_id: null, city_id: null,
clinic_type: 2, clinic_type: 1,
type: 0, type: 0,
is_shipping_free: 0, is_shipping_free: 0,
subscribe_price_change: 0, subscribe_price_change: 0,

View File

@@ -12,6 +12,7 @@
:value="show" :value="show"
mode="bottom" mode="bottom"
border-radius="24" border-radius="24"
:z-index="10090"
:safe-area-inset-bottom="true" :safe-area-inset-bottom="true"
:mask-close-able="maskCloseable" :mask-close-able="maskCloseable"
@input="onPopupInput" @input="onPopupInput"

View File

@@ -74,8 +74,6 @@ export default {
<style scoped> <style scoped>
.picker-wrap { .picker-wrap {
width: 100%; width: 100%;
position: relative;
z-index: 1;
} }
.promoter-picker { .promoter-picker {
display: flex; display: flex;

View File

@@ -6,9 +6,9 @@
<text :class="displayText ? 'region-text' : 'region-placeholder'">{{ displayText || placeholder }}</text> <text :class="displayText ? 'region-text' : 'region-placeholder'">{{ displayText || placeholder }}</text>
<view class="drawer-body"> <u-icon name="arrow-right" color="#c0c4cc" size="28"></u-icon>
<u-input v-model="keyword" placeholder="搜索省/市/区" clearable /> </view>
@@ -21,7 +21,7 @@
<u-input v-model="keyword" placeholder="搜索省/市/区" clearable :adjust-position="false" /> <u-input v-model="keyword" placeholder="搜索省/市/区" clearable :adjust-position="false" />
</view> </view>
<scroll-view scroll-y class="list-scroll">
<scroll-view scroll-x class="crumb-scroll"> <scroll-view scroll-x class="crumb-scroll">
<view class="crumbs"> <view class="crumbs">
@@ -69,6 +69,7 @@ export default {
</scroll-view> </scroll-view>
</view> </view>
</drawer-page-container> </drawer-page-container>
</view> </view>
@@ -93,9 +94,56 @@ export default {
getInitialPickerLevel, getInitialPickerLevel,
levelOptionsToRows,
searchAddressHits,
searchHitsToRows,
applySearchHit,
rowHasNextLevel,
truncateContextToBreadcrumb,
getNextLevel,
canCompleteAfterSelect,
} from '@/subPackages/sub_clinic_salesperson/utils/address-index.js'
export default {
name: 'RegionAddressPicker',
components: { DrawerPageContainer },
props: {
value: { type: Array, default: () => [] },
placeholder: { type: String, default: '请选择省市区' },
}, },
data() {
return {
show: false,
keyword: '',
currentLevel: 'province',
ctx: { provinceId: undefined, cityId: undefined, districtId: undefined },
keyboardHeight: 0,
}
}, },
computed: { computed: {
@@ -175,14 +223,14 @@ export default {
minHeight: '240rpx', minHeight: '240rpx',
} }
.drawer-body { display: flex; flex-direction: column; max-height: 70vh; }
}, },
}, },
watch: { watch: {
.list-scroll { flex: 1; max-height: 52vh; } show(val) {
if (val) { if (val) {

View File

@@ -35,19 +35,40 @@
/> />
</u-form-item> </u-form-item>
<u-form-item label="诊所类型" right-icon="arrow-right"> <u-form-item label="诊所类型" :border-bottom="false">
<u-input :value="clinicTypes[clinicTypeIndex].label" type="select" @click="showClinicType = true" placeholder="请选择" /> <view class="clinic-type-cards">
<u-select v-model="showClinicType" :list="clinicTypes" @confirm="onClinicTypeConfirm"></u-select> <view
v-for="(item, idx) in clinicTypes"
:key="item.value"
class="clinic-type-card"
:class="{ active: clinicTypeIndex === idx }"
@click="selectClinicType(idx)"
>
<text class="clinic-type-label">{{ item.label }}</text>
</view>
</view>
</u-form-item> </u-form-item>
<u-form-item label="是否包邮" right-icon="arrow-right"> <u-form-item label="是否包邮">
<u-input :value="yesNoLabel(form.is_shipping_free)" type="select" @click="showYesNo = true" placeholder="请选择" /> <view class="switch-row">
<u-select v-model="showYesNo" :list="yesNo" @confirm="e => onPickConfirm('is_shipping_free', e)"></u-select> <text class="switch-hint">{{ Number(form.is_shipping_free) === 1 ? '包邮' : '不包邮' }}</text>
<switch
:checked="Number(form.is_shipping_free) === 1"
color="#6acdbb"
@change="onShippingFreeChange"
/>
</view>
</u-form-item> </u-form-item>
<u-form-item label="订阅价格波动" right-icon="arrow-right"> <u-form-item label="订阅价格波动">
<u-input :value="subscribeOpts[form.subscribe_price_change === 1 ? 1 : 0].label" type="select" @click="showSub = true" placeholder="请选择" /> <view class="switch-row">
<u-select v-model="showSub" :list="subscribeOpts" @confirm="e => onPickConfirm('subscribe_price_change', e)"></u-select> <text class="switch-hint">{{ Number(form.subscribe_price_change) === 0 ? '订阅' : '不订阅' }}</text>
<switch
:checked="Number(form.subscribe_price_change) === 0"
color="#6acdbb"
@change="onSubscribeChange"
/>
</view>
</u-form-item> </u-form-item>
<u-form-item label="营业时间" right-icon="arrow-right"> <u-form-item label="营业时间" right-icon="arrow-right">
@@ -211,22 +232,17 @@ export default {
// uView select/picker 显示状态控制 // uView select/picker 显示状态控制
showStoreType: false, showStoreType: false,
showClinicType: false,
showYesNo: false,
showSub: false,
showStartTime: false, showStartTime: false,
showEndTime: false, showEndTime: false,
showBankType: false, showBankType: false,
clinicTypeIndex: 1, clinicTypeIndex: 0,
bankTypeIndex: 0, bankTypeIndex: 0,
// uView 格式的下拉数据 // uView 格式的下拉数据
storeTypes: [{ label: '诊所', value: 0 }, { label: '药店', value: 1 }], storeTypes: [{ label: '诊所', value: 0 }, { label: '药店', value: 1 }],
storeTypeIndex: 0, storeTypeIndex: 0,
clinicTypes: [{ label: '西医诊所', value: 1 }, { label: '中医诊所', value: 2 }], clinicTypes: [{ label: '西医诊所', value: 1 }, { label: '中医诊所', value: 2 }],
yesNo: [{ label: '不包邮', value: 0 }, { label: '包邮', value: 1 }],
subscribeOpts: [{ label: '订阅价格波动', value: 0 }, { label: '不订阅价格波动', value: 1 }],
bankTypes: [{ label: '对公', value: 1 }, { label: '对私', value: 2 }, { label: '存折', value: 5 }], bankTypes: [{ label: '对公', value: 1 }, { label: '对私', value: 2 }, { label: '存折', value: 5 }],
form: createDefaultStoreInputForm(), form: createDefaultStoreInputForm(),
@@ -306,7 +322,17 @@ export default {
this.bankTypeIndex = Math.max(0, this.bankTypes.findIndex((b) => b.value === Number(d.bank_account_type))) this.bankTypeIndex = Math.max(0, this.bankTypes.findIndex((b) => b.value === Number(d.bank_account_type)))
}) })
}, },
yesNoLabel(v) { return Number(v) === 1 ? '包邮' : '不包邮' },
selectClinicType(idx) {
this.clinicTypeIndex = idx
this.form.clinic_type = this.clinicTypes[idx].value
},
onShippingFreeChange(e) {
this.form.is_shipping_free = e.detail.value ? 1 : 0
},
onSubscribeChange(e) {
this.form.subscribe_price_change = e.detail.value ? 0 : 1
},
// --- 下拉及选择器确认事件 --- // --- 下拉及选择器确认事件 ---
onStoreTypeConfirm(e) { onStoreTypeConfirm(e) {
@@ -314,19 +340,11 @@ export default {
this.form.type = selected.value this.form.type = selected.value
this.storeTypeIndex = this.storeTypes.findIndex((item) => item.value === selected.value) this.storeTypeIndex = this.storeTypes.findIndex((item) => item.value === selected.value)
}, },
onClinicTypeConfirm(e) {
const selected = e[0];
this.form.clinic_type = selected.value;
this.clinicTypeIndex = this.clinicTypes.findIndex(item => item.value === selected.value);
},
onBankTypeConfirm(e) { onBankTypeConfirm(e) {
const selected = e[0]; const selected = e[0];
this.form.bank_account_type = selected.value; this.form.bank_account_type = selected.value;
this.bankTypeIndex = this.bankTypes.findIndex(item => item.value === selected.value); this.bankTypeIndex = this.bankTypes.findIndex(item => item.value === selected.value);
}, },
onPickConfirm(field, e) {
this.form[field] = e[0].value;
},
onTimeConfirm(field, e) { onTimeConfirm(field, e) {
this.form[field] = `${e.hour}:${e.minute}`; this.form[field] = `${e.hour}:${e.minute}`;
}, },
@@ -490,6 +508,31 @@ export default {
.time-box { flex: 1; text-align: center; background: #f5f7fa; padding: 12rpx 0; border-radius: 8rpx; font-size: 28rpx; color: #606266; } .time-box { flex: 1; text-align: center; background: #f5f7fa; padding: 12rpx 0; border-radius: 8rpx; font-size: 28rpx; color: #606266; }
.time-sep { margin: 0 20rpx; color: #999; } .time-sep { margin: 0 20rpx; color: #999; }
.clinic-type-cards { display: flex; gap: 20rpx; width: 100%; }
.clinic-type-card {
flex: 1;
padding: 24rpx 16rpx;
text-align: center;
background: #f5f7fa;
border: 2rpx solid #e4e7ed;
border-radius: 12rpx;
box-sizing: border-box;
}
.clinic-type-card.active {
background: rgba(106, 205, 187, 0.08);
border-color: #6acdbb;
}
.clinic-type-label { font-size: 28rpx; color: #303133; }
.clinic-type-card.active .clinic-type-label { color: #6acdbb; font-weight: 600; }
.switch-row {
display: flex;
align-items: center;
justify-content: flex-end;
width: 100%;
gap: 16rpx;
}
.switch-hint { font-size: 26rpx; color: #86909c; }
/* 图片资料区域 */ /* 图片资料区域 */
.upload-group { margin-bottom: 30rpx; padding-bottom: 20rpx; border-bottom: 1rpx solid #f5f5f5; } .upload-group { margin-bottom: 30rpx; padding-bottom: 20rpx; border-bottom: 1rpx solid #f5f5f5; }
.upload-group:last-child { border-bottom: none; } .upload-group:last-child { border-bottom: none; }

View File

@@ -6,8 +6,8 @@ export function checkDev(key = '') {
// 判断某些模块是否开启 // 判断某些模块是否开启
switch (key) { switch (key) {
case 'dev': case 'dev':
return false; // return false;
// return true; return true;
case 'open-im': case 'open-im':
// return false; // return false;
return true; return true;