9.20 界面502

This commit is contained in:
2025-09-20 22:09:15 +08:00
parent 44ac2723a0
commit 3894cc1c57
38 changed files with 411 additions and 241 deletions

View File

@@ -30,15 +30,15 @@
<!-- 列表 -->
<scroll-view scroll-y class="list" @scrolltolower="loadMore">
<block v-if="items.length">
<view class="item" v-for="it in items" :key="it.id" @click="openDetail(it)">
<view class="item-left">
<view class="date">{{ formatDate(it.orderTime || it.txTime || it.createdAt) }}</view>
<view class="name">{{ it.customerName || it.supplierName || it.accountName || it.remark || '-' }}</view>
<view class="no">{{ it.orderNo || it.code || it.id }}</view>
</view>
<view class="amount">¥ {{ (it.amount || 0).toFixed(2) }}</view>
<view class="arrow"></view>
<view class="item" v-for="it in items" :key="it.id" @click="openDetail(it)">
<view class="item-left">
<view class="date">{{ formatDate(it.orderTime || it.txTime || it.createdAt) }}</view>
<view class="name">{{ it.customerName || it.supplierName || it.accountName || it.remark || '-' }}</view>
<view class="no">{{ it.orderNo || it.code || it.id }}</view>
</view>
<view class="amount" :class="{ in: Number(it.amount||0) >= 0, out: Number(it.amount||0) < 0 }">¥ {{ (it.amount || 0).toFixed(2) }}</view>
<view class="arrow"></view>
</view>
</block>
<view v-else class="empty">暂无数据</view>
</scroll-view>
@@ -134,29 +134,31 @@ export default {
<style lang="scss">
.page { display:flex; flex-direction: column; height: 100vh; }
.seg { display:flex; background:$uni-bg-color-grey; }
.seg-item { flex:1; padding: 22rpx 0; text-align:center; color:$uni-text-color-grey; }
.seg-item.active { color:$uni-color-primary; font-weight: 600; }
.seg { display:flex; background:#fff; border-bottom:2rpx solid $uni-border-color; }
.seg-item { flex:1; padding: 18rpx 0; text-align:center; color:$uni-text-color-grey; }
.seg-item.active { color:#fff; background:$uni-color-primary; border-radius: 12rpx; margin: 8rpx; }
.content { display:flex; flex:1; min-height: 0; }
.biz-tabs { width: 120rpx; background:$uni-bg-color-hover; display:flex; flex-direction: column; }
.biz-tabs { width: 140rpx; background:#fff; border-right:2rpx solid $uni-border-color; display:flex; flex-direction: column; }
.biz { flex:0 0 120rpx; display:flex; align-items:center; justify-content:center; color:$uni-color-primary; }
.biz.active { background:$uni-color-primary; color:#fff; border-radius: 0 16rpx 16rpx 0; }
.biz.active { background:rgba(76,141,255,0.10); color:$uni-color-primary; font-weight:700; }
.panel { flex:1; display:flex; flex-direction: column; background:$uni-bg-color-grey; margin: 16rpx; border-radius: 16rpx; padding: 12rpx; }
.toolbar { display:flex; align-items: center; gap: 12rpx; padding: 8rpx 6rpx; }
.panel { flex:1; display:flex; flex-direction: column; background:#fff; margin: 16rpx; border-radius: 16rpx; padding: 12rpx; border:2rpx solid $uni-border-color; }
.toolbar { display:flex; align-items: center; gap: 12rpx; padding: 8rpx 6rpx; border-bottom:2rpx solid $uni-border-color; }
.search { flex:1; }
.search-input { width:100%; background:$uni-bg-color-hover; border-radius: 12rpx; padding: 12rpx; color:$uni-text-color; }
.period { color:$uni-text-color-grey; font-size: 24rpx; padding: 0 6rpx; }
.total { color:$uni-color-primary; font-weight: 700; padding: 6rpx 6rpx 12rpx; }
.total { color:$uni-color-primary; font-weight: 700; padding: 10rpx 6rpx 12rpx; background:#fff; }
.list { flex:1; }
.item { display:flex; align-items:center; padding: 20rpx 10rpx; border-bottom: 1rpx solid $uni-border-color; }
.item-left { flex:1; }
.item { display:grid; grid-template-columns: 1fr auto auto; align-items:center; gap: 8rpx; padding: 18rpx 12rpx; border-bottom: 1rpx solid $uni-border-color; }
.item-left { display:flex; flex-direction: column; }
.date { color:$uni-text-color-grey; font-size: 24rpx; }
.name { color:$uni-text-color; margin: 4rpx 0; font-weight: 600; }
.no { color:#99a2b3; font-size: 22rpx; }
.amount { color:$uni-text-color; font-weight: 700; }
.amount { color:$uni-text-color; font-weight: 700; text-align:right; }
.amount.in { color:#16a34a; }
.amount.out { color:#dc2626; }
.arrow { color:#8c99b0; font-size: 40rpx; margin-left: 8rpx; }
.empty { height: 50vh; display:flex; align-items:center; justify-content:center; color:$uni-text-color-grey; }
.fab { position: fixed; right: 30rpx; bottom: 120rpx; width: 100rpx; height: 100rpx; background:$uni-color-primary; color:#fff; border-radius: 50rpx; text-align:center; line-height: 100rpx; font-size: 48rpx; box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.15); }
.fab { position: fixed; right: 30rpx; bottom: 120rpx; width: 100rpx; height: 100rpx; background:#fff; color:$uni-color-primary; border:2rpx solid $uni-color-primary; border-radius: 50rpx; text-align:center; line-height: 100rpx; font-size: 48rpx; box-shadow: 0 8rpx 20rpx rgba(76,141,255,0.18); }
</style>

View File

@@ -1,5 +1,20 @@
<template>
<view class="home">
<!-- 公告栏置顶显示可点击查看详情 -->
<view class="notice">
<view class="notice-left">公告</view>
<view v-if="loadingNotices" class="notice-swiper" style="display:flex;align-items:center;color:#6b5a2a;">加载中...</view>
<view v-else-if="noticeError" class="notice-swiper" style="display:flex;align-items:center;color:#dd524d;">{{ noticeError }}</view>
<view v-else-if="!notices.length" class="notice-swiper" style="display:flex;align-items:center;color:#6b5a2a;">暂无公告</view>
<swiper v-else class="notice-swiper" circular autoplay interval="4000" duration="400" vertical>
<swiper-item v-for="(n, idx) in notices" :key="idx">
<view class="notice-item" @click="onNoticeTap(n)">
<text class="notice-text">{{ n.text }}</text>
<text v-if="n.tag" class="notice-tag">{{ n.tag }}</text>
</view>
</swiper-item>
</swiper>
</view>
<!-- 顶部统计卡片 -->
<view class="hero">
<view class="hero-top">
@@ -28,21 +43,7 @@
</view>
</view>
<!-- 广告栏自动轮播可点击查看详情 -->
<view class="notice">
<view class="notice-left">广告</view>
<view v-if="loadingNotices" class="notice-swiper" style="display:flex;align-items:center;color:#6b5a2a;">加载中...</view>
<view v-else-if="noticeError" class="notice-swiper" style="display:flex;align-items:center;color:#dd524d;">{{ noticeError }}</view>
<view v-else-if="!notices.length" class="notice-swiper" style="display:flex;align-items:center;color:#6b5a2a;">暂无公告</view>
<swiper v-else class="notice-swiper" circular autoplay interval="4000" duration="400" vertical>
<swiper-item v-for="(n, idx) in notices" :key="idx">
<view class="notice-item" @click="onNoticeTap(n)">
<text class="notice-text">{{ n.text }}</text>
<text v-if="n.tag" class="notice-tag">{{ n.tag }}</text>
</view>
</swiper-item>
</swiper>
</view>
<!-- 告栏已上移到顶部 -->
<!-- 分割标题产品与功能 -->
<view class="section-title">
@@ -51,14 +52,14 @@
<!-- 功能九宫格玻璃容器 + 圆角方形图标 -->
<view class="grid-wrap">
<view class="grid">
<view class="grid-item" v-for="item in features" :key="item.key" @click="onFeatureTap(item)">
<view class="icon icon-squircle">
<image v-if="item.img" :src="item.img" class="icon-img" mode="aspectFit" @error="onIconError(item)"></image>
<text v-else-if="item.emoji" class="icon-emoji">{{ item.emoji }}</text>
<view v-else class="icon-placeholder"></view>
<view class="feature-grid">
<view class="feature-card" v-for="item in features" :key="item.key" @click="onFeatureTap(item)">
<view class="fc-icon">
<image v-if="item.img" :src="item.img" class="fc-img" mode="aspectFit" @error="onIconError(item)"></image>
<text v-else-if="item.emoji" class="fc-emoji">{{ item.emoji }}</text>
<view v-else class="fc-placeholder"></view>
</view>
<text class="grid-chip">{{ item.title }}</text>
<view class="fc-title">{{ item.title }}</view>
</view>
</view>
</view>
@@ -271,8 +272,9 @@
.cta-text { color: #fff; font-size: 30rpx; font-weight: 700; letter-spacing: 1rpx; }
.kpi { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8rpx; }
.kpi-item { text-align: center; }
/* KPI 卡片化布局2×2 */
.kpi { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16rpx; }
.kpi-item { text-align: center; background:#ffffff; border: 2rpx solid $uni-border-color; border-radius: 16rpx; padding: 16rpx 8rpx; }
.kpi-label {
opacity: 0.9;
font-size: 26rpx;
@@ -286,6 +288,13 @@
}
.kpi-value { display: block; margin-top: 8rpx; font-size: 56rpx; font-weight: 800; color: $uni-color-primary; }
/* 常用功能:胶囊+阴影卡片样式的图标栅格(旧风格保留以防回退) */
.grid { grid-row-gap: 36rpx; grid-column-gap: 26rpx; padding: 32rpx 24rpx 28rpx; }
.grid-item { position: relative; }
.icon-squircle { width: 140rpx; height: 140rpx; border-radius: 28rpx; background: #fff; border: 2rpx solid $uni-border-color; box-shadow: 0 10rpx 20rpx rgba(0,0,0,0.06); }
.grid-chip { margin-top: 12rpx; padding: 6rpx 14rpx; border-radius: 999rpx; background: rgba(76,141,255,0.12); color: $uni-color-primary; font-size: 26rpx; font-weight: 700; }
/* 功能容器:整体玻璃面板,增强融入感 */
.grid-wrap {
margin: 0 20rpx 32rpx;
@@ -296,32 +305,14 @@
box-shadow: none;
}
/* 功能九宫格 */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-row-gap: 64rpx;
grid-column-gap: 36rpx;
padding: 40rpx 28rpx 28rpx;
}
.grid-item { display: flex; flex-direction: column; align-items: center; text-align: center; }
.icon { display: flex; align-items: center; justify-content: center; color: $uni-text-color; position: relative; }
.icon-squircle {
width: 132rpx; height: 132rpx;
border-radius: 28rpx;
background: $uni-bg-color-hover;
border: 2rpx solid $uni-border-color;
box-shadow: none;
overflow: hidden;
}
.icon-squircle::before { content: ''; position: absolute; left: -30%; top: -40%; width: 160%; height: 70%; background: linear-gradient( to bottom, rgba(255,255,255,0.9), rgba(255,255,255,0.0) ); transform: rotate(12deg); }
.icon-img { width: 96rpx; height: 96rpx; }
.icon-emoji { font-size: 60rpx; line-height: 1; }
.icon-placeholder { width: 84rpx; height: 84rpx; border-radius: 18rpx; background: $uni-bg-color-hover; border: 2rpx solid $uni-border-color; box-shadow: none; }
.icon-text { font-size: 46rpx; font-weight: 700; }
.grid-title { display: none; }
.grid-chip { margin-top: 14rpx; padding: 8rpx 16rpx; border-radius: 999rpx; background: $uni-color-primary; color: #fff; font-size: 28rpx; font-weight: 700; }
/* 新版功能卡片宫格(更现代卡片风) */
.feature-grid { display:grid; grid-template-columns: repeat(2, 1fr); gap: 18rpx; padding: 18rpx 18rpx 24rpx; }
.feature-card { background:#fff; border:2rpx solid $uni-border-color; border-radius: 16rpx; box-shadow: 0 10rpx 20rpx rgba(0,0,0,0.06); padding: 18rpx; display:flex; align-items:center; gap: 12rpx; }
.fc-icon { width: 96rpx; height: 96rpx; border-radius: 16rpx; background: $uni-bg-color-hover; display:flex; align-items:center; justify-content:center; }
.fc-img { width: 72rpx; height: 72rpx; }
.fc-emoji { font-size: 56rpx; }
.fc-placeholder { width: 72rpx; height: 72rpx; border-radius: 12rpx; background: $uni-bg-color-hover; border: 2rpx solid $uni-border-color; }
.fc-title { margin-left: 2rpx; font-size: 30rpx; font-weight: 700; color: $uni-text-color; }
/* 底部操作条:浅色半透明 + 金色主按钮 */
.bottom-bar {

View File

@@ -78,6 +78,23 @@
<!-- 已选商品与合计销售/进货 出入库 -->
<view v-else-if="biz==='sale' || biz==='purchase'">
<!-- 快捷操作加商品/选择客户(或供应商)/选择日期 不改功能只换排版 -->
<view class="info-card">
<view class="info-field" @click="biz==='sale' ? chooseCustomer() : chooseSupplier()">
<text class="info-label">{{ biz==='sale' ? '客户' : '供应商' }}</text>
<text class="info-value">{{ biz==='sale' ? customerLabel : supplierLabel }}</text>
</view>
<picker class="info-field" mode="date" :value="order.orderTime" @change="onDateChange">
<view>
<text class="info-label">时间</text>
<text class="info-value">{{ order.orderTime }}</text>
</view>
</picker>
<button class="info-action" @click="chooseProduct">
<image src="/static/icons/icons8-shopping-cart-100.png" class="info-icon" mode="aspectFit" />
<text>加商品</text>
</button>
</view>
<view class="summary">
<text>选中货品{{ totalQuantity }}</text>
<text>合计金额¥ {{ totalAmount.toFixed(2) }}</text>
@@ -116,7 +133,7 @@
<!-- 购物车空态 -->
<view class="empty" v-if="!items.length">
<image src="/static/logo.png" mode="widthFix" class="empty-img"></image>
<image src="/static/icons/icons8-shopping-cart-100.png" mode="widthFix" class="empty-img"></image>
<text class="empty-text">购物车里空空如也</text>
<text class="empty-sub">扫描或点击 + 选择商品吧</text>
</view>
@@ -355,12 +372,14 @@
.field { display:flex; justify-content: space-between; padding: 22rpx 24rpx; background: $uni-bg-color-grey; border-bottom: 1rpx solid $uni-border-color; }
.label { color:$uni-text-color-grey; }
.value { color:$uni-text-color; }
.summary { display:flex; justify-content: space-between; padding: 22rpx 24rpx; color:$uni-text-color; }
.add { margin: 24rpx auto; width: 120rpx; height: 120rpx; border-radius: 20rpx; background: $uni-color-primary; color:#fff; font-size: 72rpx; display:flex; align-items:center; justify-content:center; }
/* 汇总卡片:白底卡片+主色按钮 */
.summary { display:flex; justify-content: space-between; align-items:center; padding: 16rpx 18rpx; margin: 12rpx 16rpx; background:#fff; border:2rpx solid $uni-border-color; border-radius: 16rpx; color:$uni-text-color; }
/* 加号改为图标按钮 */
.add { margin: 18rpx auto; width: 120rpx; height: 120rpx; border-radius: 24rpx; background: #fff; border:2rpx solid $uni-color-primary; color:$uni-color-primary; font-size: 72rpx; display:flex; align-items:center; justify-content:center; box-shadow: 0 6rpx 16rpx rgba(76,141,255,0.12); }
.empty { display:flex; flex-direction: column; align-items:center; padding: 60rpx 0; color:$uni-text-color-grey; }
.empty-img { width: 220rpx; margin-bottom: 20rpx; }
.empty-img { width: 160rpx; margin-bottom: 16rpx; }
.empty-text { margin-bottom: 8rpx; }
.list { background:$uni-bg-color-grey; }
.list { background:#fff; margin: 0 16rpx 12rpx; border:2rpx solid $uni-border-color; border-radius: 16rpx; overflow: hidden; }
.row { display:grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 12rpx; padding: 16rpx 12rpx; align-items:center; border-bottom: 1rpx solid $uni-border-color; }
.col.name { padding-left: 12rpx; }
.col.amount { text-align:right; padding-right: 12rpx; color:$uni-text-color; }
@@ -375,6 +394,18 @@
.chips { display:flex; flex-wrap: wrap; gap: 12rpx; padding: 12rpx 24rpx; }
.chip { padding: 10rpx 20rpx; border-radius: 999rpx; background: $uni-bg-color-hover; color:$uni-text-color-grey; }
.chip.active { background: $uni-color-primary; color:#fff; }
/* 顶部旧 tabs 简化隐藏(改为更简洁布局) */
.tabs { display: none; }
/* 快捷操作宫格 */
/* 信息卡片式表达(更稳重) */
.info-card { display:grid; grid-template-columns: 1fr 1fr auto; gap: 10rpx; margin: 12rpx 16rpx 0; background:#fff; border:2rpx solid $uni-border-color; border-radius: 16rpx; padding: 10rpx; align-items:center; }
.info-field { background:$uni-bg-color-grey; border:2rpx solid $uni-border-color; border-radius: 12rpx; padding: 10rpx 12rpx; }
.info-label { color:$uni-text-color-grey; font-size: 24rpx; margin-right: 8rpx; }
.info-value { color:$uni-text-color; font-weight: 700; }
.info-action { display:flex; align-items:center; gap: 6rpx; background:$uni-color-primary; color:#fff; border-radius: 12rpx; padding: 12rpx 14rpx; }
.info-icon { width: 32rpx; height: 32rpx; }
</style>

View File

@@ -1,6 +1,11 @@
<template>
<scroll-view scroll-y class="page">
<view class="card">
<scroll-view scroll-y class="page">
<!-- 顶部标题与操作提示 -->
<view class="hero small">
<text class="title">编辑货品</text>
<text class="sub">完善基础信息与价格</text>
</view>
<view class="card">
<view class="row">
<text class="label">商品名称</text>
<input v-model.trim="form.name" placeholder="必填" />
@@ -37,7 +42,7 @@
</view>
</view>
<view class="card">
<view class="card">
<view class="row">
<text class="label">库存与安全库存</text>
</view>
@@ -70,10 +75,10 @@
<textarea v-model.trim="form.remark" placeholder="可选" auto-height />
</view>
<view class="fixed">
<button type="default" @click="save(false)">保存</button>
<button type="primary" @click="save(true)">保存并继续</button>
</view>
<view class="fixed">
<button class="ghost" @click="save(false)">保存</button>
<button class="primary" @click="save(true)">保存并继续</button>
</view>
</scroll-view>
</template>
@@ -201,13 +206,18 @@ export default {
<style lang="scss">
.page { background:$uni-bg-color; height: 100vh; }
.card { background:$uni-bg-color-grey; margin: 16rpx; padding: 16rpx; border-radius: 12rpx; }
.hero.small { margin: 16rpx; padding: 16rpx; background: #ffffff; border: 2rpx solid $uni-border-color; border-radius: 16rpx; }
.hero.small .title { font-size: 32rpx; font-weight: 800; color: $uni-text-color; }
.hero.small .sub { margin-left: 12rpx; color: $uni-text-color-grey; font-size: 24rpx; }
.card { background:#ffffff; margin: 16rpx; padding: 16rpx; border-radius: 16rpx; border: 2rpx solid $uni-border-color; }
.row { display:flex; gap: 12rpx; align-items: center; margin-bottom: 12rpx; }
.label { width: 180rpx; color:$uni-text-color-grey; }
.row input { flex:1; background:$uni-bg-color-hover; border-radius: 10rpx; padding: 12rpx; color:$uni-text-color; }
.picker { padding: 8rpx 12rpx; background:$uni-bg-color-hover; border-radius: 10rpx; color:$uni-text-color-grey; margin-left: 8rpx; }
.row input { flex:1; background:$uni-bg-color-hover; border-radius: 12rpx; padding: 14rpx; color:$uni-text-color; border: 2rpx solid $uni-border-color; }
.picker { padding: 10rpx 14rpx; background:$uni-bg-color-hover; border-radius: 12rpx; color:$uni-text-color-grey; margin-left: 8rpx; border: 2rpx solid $uni-border-color; }
.prices input { width: 30%; }
.fixed { position: fixed; left: 0; right: 0; bottom: 0; background:$uni-bg-color-grey; padding: 12rpx 16rpx; display:flex; gap: 16rpx; }
.fixed { position: fixed; left: 0; right: 0; bottom: 0; background:#ffffff; padding: 12rpx 16rpx; display:flex; gap: 16rpx; border-top: 2rpx solid $uni-border-color; }
.fixed .primary { flex:1; background: $uni-color-primary; color:#fff; border-radius: 999rpx; padding: 18rpx 0; font-weight: 700; }
.fixed .ghost { flex:1; background:#ffffff; color:$uni-color-primary; border: 2rpx solid rgba($uni-color-primary, .45); border-radius: 999rpx; padding: 18rpx 0; }
</style>