| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889 |
- <script setup>
- import { computed, onUnmounted, ref, watch } from 'vue';
- import { onLoad, onShow } from '@dcloudio/uni-app';
- import { useUserStore } from '@/stores/user';
- import { request, parseResponseJson } from '@/utils/request';
- import { formatDateTime } from '@/utils/date';
- import { formatYuan } from '@/utils/format';
- import PhoneDialInline from '@/components/phone-dial-inline.vue';
- import { DEFAULT_PLACEHOLDER_IMAGE_URL, IMG_EMPTY } from '@/utils/staticAsset';
- import ClientSkeleton from '@/components/client/client-skeleton.vue';
- import SqCopyBtn from '@/components/sq-copy-btn.vue';
- const userStore = useUserStore();
- const PAGE_SIZE = 10;
- function taskItemImage(it) {
- return it.imageUrl || DEFAULT_PLACEHOLDER_IMAGE_URL;
- }
- function taskQtyText(it) {
- const q = Number(it?.quantity ?? 0);
- if (!Number.isFinite(q))
- return 'x0';
- const n = Number.isInteger(q) ? String(q) : String(q).replace(/\.?0+$/, '');
- return `x${n}`;
- }
- function formatTaskTotalQty(row) {
- const n = row.totalQuantity;
- if (n != null && !Number.isNaN(Number(n))) {
- const num = Number(n);
- if (Number.isInteger(num))
- return String(num);
- return num.toFixed(3).replace(/\.?0+$/, '') || '0';
- }
- const list = row.items || [];
- const sum = list.reduce((acc, it) => acc + (Number(it.quantity) || 0), 0);
- if (Number.isInteger(sum))
- return String(sum);
- return String(sum);
- }
- function taskFooterTime(row) {
- if (row.effectiveTime)
- return `送达截止 ${row.effectiveTime}`;
- if (row.createAt)
- return formatDateTime(row.createAt);
- return '';
- }
- const list = ref([]);
- const page = ref(0);
- const total = ref(0);
- const totalPages = ref(0);
- const loading = ref(false);
- const pageLoading = ref(true);
- const initialLoaded = ref(false);
- const keyword = ref('');
- /** 与接口同步的检索关键字(防抖后触发请求) */
- const keywordQuery = ref('');
- /** loading 期间收到重置请求时,当前请求结束后立即重拉 */
- const pendingResetFetch = ref(false);
- /** 请求序号:只允许最新请求回填列表,避免旧请求覆盖新筛选 */
- let fetchSeq = 0;
- const status = ref('');
- /** Tab 与 supplier_prepare_status 对应(逗号多选由后端 IN 查询) */
- const statusTabs = [
- { key: '', label: '全部' },
- { key: 'pending_prepare', label: '待备货' },
- { key: 'stocking,prepared', label: '备货中' },
- { key: 'picked_up', label: '已完成' }
- ];
- const prepareStatusText = {
- pending_prepare: '待备货',
- stocking: '备货中',
- prepared: '备货完成',
- picked_up: '已取货'
- };
- const statusText = {
- pending: '待分配',
- assigned: '待备货',
- supplier_stocking: '备货中',
- supplier_ready: '备货完成',
- picking: '取货/配送中',
- picked: '待取货',
- delivering: '配送中',
- completed: '已完成',
- cancelled: '已取消'
- };
- function displayStatus(row) {
- const ps = String(row.supplierPrepareStatus || '').toLowerCase();
- if (ps && prepareStatusText[ps])
- return prepareStatusText[ps];
- const code = String(row.status || '').toLowerCase();
- if (!code)
- return '-';
- return statusText[code] || code;
- }
- /** onLoad 入参优先;H5 等场景若为空则从当前页 options 兜底 */
- function resolvePageRouteOptions(options) {
- const o = options && typeof options === 'object' ? options : {};
- if (Object.keys(o).length > 0)
- return o;
- try {
- const pages = getCurrentPages();
- const cur = pages[pages.length - 1];
- return { ...(cur?.options ?? {}) };
- }
- catch {
- return {};
- }
- }
- function applyStatusFromRouteOptions(opts) {
- const rawPrep = opts.supplierPrepareStatus;
- const raw = opts.status;
- if (rawPrep != null && String(rawPrep).trim() !== '') {
- try {
- status.value = decodeURIComponent(String(rawPrep));
- }
- catch {
- status.value = String(rawPrep);
- }
- }
- else if (raw != null && String(raw).trim() !== '') {
- try {
- const s = decodeURIComponent(String(raw));
- if (s === 'assigned')
- status.value = 'pending_prepare';
- else if (['supplier_stocking', 'supplier_ready', 'picking', 'delivering'].some((x) => s.includes(x)))
- status.value = 'stocking,prepared';
- else if (s === 'completed')
- status.value = 'picked_up';
- else
- status.value = s;
- }
- catch {
- status.value = String(raw);
- }
- }
- }
- async function fetchPage(reset) {
- if (loading.value) {
- if (reset)
- pendingResetFetch.value = true;
- return;
- }
- if (!reset) {
- if (!initialLoaded.value)
- return;
- if (total.value === 0)
- return;
- const tp = totalPages.value || (total.value > 0 ? Math.ceil(total.value / PAGE_SIZE) : 0);
- if (tp > 0 && page.value >= tp)
- return;
- if (list.value.length >= total.value)
- return;
- }
- if (reset) {
- list.value = [];
- page.value = 0;
- total.value = 0;
- totalPages.value = 0;
- initialLoaded.value = false;
- }
- loading.value = true;
- pendingResetFetch.value = false;
- const nextPage = reset ? 1 : page.value + 1;
- const reqStatus = status.value;
- const reqKeyword = keywordQuery.value.trim();
- const currentFetchSeq = ++fetchSeq;
- try {
- const data = {
- page: nextPage,
- pageSize: PAGE_SIZE
- };
- if (reqStatus)
- data.supplierPrepareStatus = reqStatus;
- if (reqKeyword)
- data.keyword = reqKeyword;
- const res = await request({
- url: '/mini/supplier/tasks',
- method: 'GET',
- data
- });
- const body = parseResponseJson(res);
- if (body.code !== 200) {
- if (reset)
- list.value = [];
- return;
- }
- // 仅处理最新请求,防止旧请求结果覆盖最新筛选
- if (currentFetchSeq !== fetchSeq)
- return;
- const rawList = body.data?.list || [];
- if (reset) {
- list.value = rawList;
- }
- else {
- const ids = new Set(list.value.map((r) => r.id));
- for (const row of rawList) {
- if (row.id && !ids.has(row.id)) {
- list.value.push(row);
- ids.add(row.id);
- }
- }
- }
- page.value = nextPage;
- total.value = Number(body.data?.total ?? 0);
- totalPages.value = Number(body.data?.totalPages ?? 0);
- initialLoaded.value = true;
- }
- finally {
- loading.value = false;
- if (pendingResetFetch.value) {
- pendingResetFetch.value = false;
- void fetchPage(true);
- }
- }
- }
- function onScrollToLower() {
- if (!initialLoaded.value || loading.value)
- return;
- if (total.value === 0)
- return;
- const tp = totalPages.value || (total.value > 0 ? Math.ceil(total.value / PAGE_SIZE) : 0);
- if (tp > 0 && page.value >= tp)
- return;
- if (list.value.length >= total.value)
- return;
- void fetchPage(false);
- }
- function setStatus(key) {
- status.value = key;
- void fetchPage(true);
- }
- const emptyHint = computed(() => {
- if (keywordQuery.value.trim() && list.value.length === 0 && initialLoaded.value) {
- return '未找到匹配任务';
- }
- return '暂无备货任务';
- });
- function goDetail(id) {
- if (!id)
- return;
- uni.navigateTo({
- url: `/pages/supplier/delivery/detail/detail?id=${encodeURIComponent(id)}`
- });
- }
- function canStartStock(row) {
- const ps = String(row.supplierPrepareStatus || '').toLowerCase();
- if (ps === 'pending_prepare')
- return true;
- return !row.supplierPrepareStatus && String(row.status || '').toLowerCase() === 'assigned';
- }
- function canFinishStock(row) {
- const ps = String(row.supplierPrepareStatus || '').toLowerCase();
- if (ps === 'stocking')
- return true;
- return !row.supplierPrepareStatus && String(row.status || '').toLowerCase() === 'supplier_stocking';
- }
- function onGoTaskDetail(row, e) {
- e?.stopPropagation?.();
- goDetail(row?.id);
- }
- let keywordDebounce = null;
- function onSearchConfirm() {
- if (keywordDebounce) {
- clearTimeout(keywordDebounce);
- keywordDebounce = null;
- }
- keywordQuery.value = keyword.value.trim();
- void fetchPage(true);
- }
- function clearKeyword() {
- if (keywordDebounce) {
- clearTimeout(keywordDebounce);
- keywordDebounce = null;
- }
- keyword.value = '';
- keywordQuery.value = '';
- void fetchPage(true);
- }
- watch(keyword, () => {
- if (keywordDebounce)
- clearTimeout(keywordDebounce);
- keywordDebounce = setTimeout(() => {
- keywordDebounce = null;
- keywordQuery.value = keyword.value.trim();
- void fetchPage(true);
- }, 400);
- });
- onUnmounted(() => {
- if (keywordDebounce)
- clearTimeout(keywordDebounce);
- });
- /**
- * 必须在 onShow 之前执行:原先 onShow 先发起无 supplierPrepareStatus 的请求并占用 loading,
- * onMounted 再设 Tab 后 fetch会被 loading 短路,导致 URL 带参仍展示「全部」。
- */
- onLoad((options) => {
- if (!userStore.isLoggedIn) {
- uni.reLaunch({ url: '/pages/login/login' });
- return;
- }
- if (!userStore.isSupplier) {
- uni.showToast({ title: '仅供应商可访问', icon: 'none' });
- setTimeout(() => userStore.navigateToHome(), 1200);
- return;
- }
- try {
- applyStatusFromRouteOptions(resolvePageRouteOptions(options));
- }
- catch {
- // ignore
- }
- keywordQuery.value = keyword.value.trim();
- (async () => {
- try {
- await fetchPage(true);
- }
- finally {
- pageLoading.value = false;
- }
- })();
- });
- onShow(() => {
- if (!userStore.isLoggedIn || !userStore.isSupplier)
- return;
- if (!initialLoaded.value)
- return;
- void fetchPage(true);
- });
- </script>
- <template>
- <view class="delivery-root">
- <view v-if="pageLoading" class="page-loading-wrap">
- <ClientSkeleton variant="hero-list" :rows="3" />
- </view>
- <view v-else class="delivery-page">
- <view class="delivery-top">
- <view class="search-wrap">
- <view class="search-bar">
- <input
- v-model="keyword"
- class="search-input"
- type="text"
- confirm-type="search"
- placeholder="配送单号 / 订单号 / 联系人 / 电话"
- @confirm="onSearchConfirm"
- />
- <text class="search-action" @click="onSearchConfirm">搜索</text>
- </view>
- </view>
- <scroll-view scroll-x class="tabs-scroll" :show-scrollbar="false" :enable-flex="true">
- <view class="tabs-row">
- <view
- v-for="t in statusTabs"
- :key="t.key || 'all'"
- class="tab"
- :class="{ active: (t.key || '') === status }"
- @click="setStatus(t.key)"
- >
- <text>{{ t.label }}</text>
- </view>
- </view>
- </scroll-view>
- </view>
- <scroll-view
- scroll-y
- class="list"
- :enable-flex="true"
- :lower-threshold="100"
- :show-scrollbar="true"
- @scrolltolower="onScrollToLower"
- >
- <view v-for="(row, idx) in list" :key="row.id" class="card" @click="goDetail(row.id)">
- <view class="row top-row">
- <view class="no-line">
- <text class="no">{{ idx + 1 }}. 任务号:{{ row.taskNo || row.id }}</text>
- <SqCopyBtn class="no-copy" :text="row.taskNo || row.id" label="任务号" />
- </view>
- <text class="st" :class="String(row.status || '')">{{ displayStatus(row) }}</text>
- </view>
- <view
- v-if="canStartStock(row) || canFinishStock(row)"
- class="action-row"
- @click.stop
- >
- <button
- v-if="canStartStock(row)"
- class="sq-stock-btn sq-stock-btn--outline"
- @click="onGoTaskDetail(row, $event)"
- >
- 开始备货
- </button>
- <button
- v-if="canFinishStock(row)"
- class="btn-act btn-done"
- @click="onGoTaskDetail(row, $event)"
- >
- 备货完成
- </button>
- </view>
- <view v-if="row.deliverName" class="meta">配送员:{{ row.deliverName }}</view>
- <view v-if="row.deliverPhone" class="meta meta-with-dial">
- <text>联系电话:</text>
- <PhoneDialInline :phone="row.deliverPhone" color="#303133" expand />
- </view>
- <view v-if="(row.deliveredItems ?? 0) > 0" class="meta delivered-hint">
- 已送达行:{{ row.deliveredItems }}
- </view>
- <view v-if="(row.items || []).length" class="product-scroll">
- <view class="product-scroll-inner">
- <view v-for="it in row.items || []" :key="it.id" class="product-card">
- <ClientImageLoader class="product-image" :src="taskItemImage(it)" mode="aspectFill" />
- <view class="product-meta">
- <text class="product-name">{{ it.productName || '-' }}</text>
- <text class="product-qty">{{ taskQtyText(it) }}</text>
- </view>
- </view>
- </view>
- </view>
- <view class="task-card-footer">
- <view class="footer-left">
- <text v-if="row.effectiveTime || row.createAt" class="footer-time">{{ taskFooterTime(row) }}</text>
- </view>
- <view class="footer-amount">
- <text class="amount-count">共{{ formatTaskTotalQty(row) }}件</text>
- <view class="amount-row">
- <text class="amount-label">供货合计(元):</text>
- <text class="amount-value">¥{{ formatYuan(row.supplierQuoteTotal) }}</text>
- </view>
- </view>
- </view>
- </view>
- <view v-if="list.length === 0 && !loading && initialLoaded" class="empty-state">
- <view class="empty-inner">
- <image class="empty-image" :src="IMG_EMPTY" mode="aspectFit" />
- <text class="empty-text">{{ emptyHint }}</text>
- </view>
- </view>
- <ClientSkeleton v-if="loading && list.length === 0" variant="list" :rows="2" />
- <view v-if="loading && list.length > 0" class="loading-more">
- <text>加载中...</text>
- </view>
- <view
- v-else-if="
- initialLoaded &&
- total > 0 &&
- (totalPages > 0 ? page >= totalPages : list.length >= total)
- "
- class="nomore"
- >
- <text>没有更多了</text>
- </view>
- </scroll-view>
- </view>
- </view>
- </template>
- <style lang="scss">
- page {
- height: 100%;
- overflow: hidden;
- }
- </style>
- <style lang="scss" scoped>
- .page-loading-wrap {
- min-height: 100vh;
- }
- .delivery-root {
- position: relative;
- width: 100%;
- min-height: 100%;
- }
- /* #ifdef H5 */
- .delivery-page {
- position: fixed;
- left: 0;
- right: 0;
- top: var(--window-top, 0px);
- bottom: var(--window-bottom, 0px);
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- z-index: 1;
- display: flex;
- flex-direction: column;
- background: #f3f7f5;
- overflow: hidden;
- padding: 20rpx;
- }
- /* #endif */
- /* #ifndef H5 */
- .delivery-page {
- height: 100%;
- max-height: 100%;
- min-height: 0;
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- background: #f3f7f5;
- overflow: hidden;
- padding: 20rpx;
- }
- /* #endif */
- .delivery-top {
- flex-shrink: 0;
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- }
- .search-wrap {
- margin-bottom: 8rpx;
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- }
- .search-bar {
- display: flex;
- align-items: center;
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- height: 72rpx;
- background: #fff;
- border: 1rpx solid #d9e9e1;
- border-radius: 36rpx;
- padding: 0 8rpx 0 24rpx;
- }
- .search-input {
- flex: 1;
- min-width: 0;
- height: 72rpx;
- box-sizing: border-box;
- background: transparent;
- font-size: 28rpx;
- color: #303133;
- border: none;
- padding: 0;
- }
- .search-action {
- flex-shrink: 0;
- padding: 0 16rpx 0 8rpx;
- font-size: 24rpx;
- color: #0a9f6d;
- font-weight: 600;
- }
- .tabs-scroll {
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- margin-bottom: 16rpx;
- background: transparent;
- padding: 8rpx 0 0;
- }
- .tabs-row {
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- justify-content: flex-start;
- align-items: center;
- width: max-content;
- min-width: 100%;
- box-sizing: border-box;
- }
- .tabs-row .tab {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- padding: 8rpx 12rpx 12rpx 0;
- margin-right: 24rpx;
- font-size: 26rpx;
- color: #606266;
- background: transparent;
- }
- .tabs-row .tab:last-child {
- margin-right: 0;
- }
- .tabs-row .tab.active {
- color: #0a9f6d;
- font-weight: 600;
- }
- .list {
- flex: 1;
- min-height: 0;
- height: 100%;
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- overflow: hidden;
- }
- .card {
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- overflow: hidden;
- background: #fff;
- border-radius: 14px;
- border: 1px solid #d9e9e1;
- padding: 24rpx;
- margin-bottom: 16rpx;
- box-shadow: 0 4px 12px rgba(10, 159, 109, 0.06);
- .row {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- gap: 16rpx;
- margin-bottom: 12rpx;
- }
- .top-row {
- align-items: center;
- }
- .no {
- font-size: 28rpx;
- color: #303133;
- font-weight: 500;
- word-break: break-all;
- }
- .no-line {
- flex: 1;
- min-width: 0;
- display: flex;
- align-items: center;
- gap: 10rpx;
- }
- .no-line .no {
- flex: 1;
- min-width: 0;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .no-copy {
- flex-shrink: 0;
- }
- .st {
- flex-shrink: 0;
- font-size: 22rpx;
- color: #cf8a19;
- padding: 4rpx 12rpx;
- border-radius: 8rpx;
- background: #fff4dd;
- max-width: 42%;
- text-align: center;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .st.completed {
- color: #07c160;
- background: #f0f9eb;
- }
- .st.cancelled {
- color: #909399;
- background: #f4f4f5;
- }
- .meta {
- font-size: 24rpx;
- color: #606266;
- line-height: 1.5;
- word-break: break-all;
- max-width: 100%;
- }
- .meta-with-dial {
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- gap: 8rpx;
- }
- .meta-with-dial :deep(.phone-dial-inline__text) {
- font-size: 24rpx;
- color: #303133;
- }
- .action-row {
- display: flex;
- flex-wrap: wrap;
- gap: 16rpx;
- margin-bottom: 8rpx;
- }
- .btn-act {
- flex: 1;
- min-width: 200rpx;
- height: 64rpx;
- line-height: 64rpx;
- font-size: 26rpx;
- border-radius: 12rpx;
- padding: 0;
- margin: 0;
- border: none;
- }
- .btn-act::after {
- border: none;
- }
- .btn-done {
- background: linear-gradient(145deg, #087f57, #0a9f6d);
- color: #fff;
- font-weight: 500;
- }
- /* 对齐备货详情页「开始备货」按钮样式 */
- .sq-stock-btn {
- flex: 1;
- min-width: 200rpx;
- height: 72rpx;
- line-height: 72rpx;
- font-size: 28rpx;
- border-radius: 12rpx;
- padding: 0;
- margin: 0;
- border: none;
- }
- .sq-stock-btn::after {
- border: none;
- }
- .sq-stock-btn--outline {
- background: #ecfdf5;
- color: #087f57;
- font-weight: 600;
- }
- .delivered-hint {
- margin-top: 6rpx;
- color: #07c160;
- }
- .product-scroll {
- margin-top: 12rpx;
- padding-bottom: 16rpx;
- border-bottom: 1rpx solid #f5f5f5;
- width: 100%;
- overflow-x: auto;
- overflow-y: hidden;
- -webkit-overflow-scrolling: touch;
- }
- .product-scroll-inner {
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- gap: 16rpx;
- padding: 0 2rpx;
- width: max-content;
- max-width: none;
- }
- .product-card {
- width: 168rpx;
- border-radius: 12rpx;
- overflow: hidden;
- background: #ffffff;
- border: 1rpx solid #e8f3ee;
- flex: 0 0 auto;
- }
- .product-image {
- width: 100%;
- height: 120rpx;
- background: #ebeef5;
- display: block;
- }
- .product-meta {
- display: flex;
- align-items: center;
- padding: 12rpx;
- gap: 8rpx;
- }
- .product-name {
- flex: 1;
- min-width: 0;
- font-size: 24rpx;
- color: #303133;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .product-qty {
- font-size: 24rpx;
- color: #909399;
- flex: 0 0 auto;
- }
- .task-card-footer {
- display: flex;
- justify-content: space-between;
- align-items: flex-end;
- margin-top: 16rpx;
- gap: 16rpx;
- }
- .footer-left {
- flex: 1;
- min-width: 0;
- }
- .footer-time {
- font-size: 24rpx;
- color: #909399;
- line-height: 1.4;
- word-break: break-all;
- }
- .footer-amount {
- display: flex;
- flex-direction: column;
- align-items: flex-end;
- flex-shrink: 0;
- }
- .amount-count {
- font-size: 24rpx;
- color: #909399;
- margin-bottom: 6rpx;
- }
- .amount-row {
- display: flex;
- align-items: baseline;
- }
- .amount-label {
- font-size: 26rpx;
- color: #606266;
- }
- .amount-value {
- font-size: 32rpx;
- color: #be7a12;
- font-weight: bold;
- }
- }
- .empty-state {
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 88rpx 32rpx 112rpx;
- }
- .empty-inner {
- width: 100%;
- max-width: 100%;
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- .empty-image {
- display: block;
- width: 160rpx;
- height: 160rpx;
- margin-bottom: 10rpx;
- }
- .empty-text {
- display: block;
- width: 100%;
- max-width: 560rpx;
- box-sizing: border-box;
- text-align: center;
- font-size: 28rpx;
- color: #909399;
- line-height: 1.45;
- padding: 0 16rpx;
- margin-top: 0;
- }
- .loading-state,
- .loading-more,
- .nomore {
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 32rpx 0;
- color: #909399;
- font-size: 26rpx;
- }
- </style>
|