Commit e739c8f1 by liangjianmin

Integrate uView UI components and SCSS styles across application pages,…

Integrate uView UI components and SCSS styles across application pages, enhancing form functionality in apply and approve pages, and improving overall layout and design consistency.
parent 5e3c61e6
...@@ -14,7 +14,8 @@ ...@@ -14,7 +14,8 @@
}; };
</script> </script>
<style> <style lang="scss">
@import '@/uni_modules/uview-ui/index.scss';
@import './assets/css/font.css'; @import './assets/css/font.css';
page { page {
......
.apply-page {
min-height: 100vh;
background: #f5f7fa;
padding-bottom: 180rpx;
.form-section {
background: #ffffff;
margin-bottom: 20rpx;
padding: 0 32rpx;
.section-header {
font-size: 28rpx;
font-weight: 600;
color: #909399;
padding: 24rpx 0 0;
}
.currency-hint {
font-size: 24rpx;
color: #909399;
padding: 0 0 20rpx;
margin-top: -16rpx;
line-height: 1;
}
.link-text {
font-size: 26rpx;
color: #3b82f6;
}
}
.error-tip {
padding: 24rpx 32rpx;
.error-text {
font-size: 26rpx;
color: #f56c6c;
margin-left: 8rpx;
}
}
.bottom-btn {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 48rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
background: #ffffff;
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
z-index: 100;
}
}
.approve-page {
min-height: 100vh;
background: #f5f7fa;
padding-bottom: 158rpx;
.search-bar {
padding: 20rpx 28rpx;
background: #ffffff;
}
.filter-bar {
padding: 20rpx 28rpx;
background: #ffffff;
margin-bottom: 20rpx;
.filter-btn {
padding: 12rpx 24rpx;
background: #f5f7fa;
border-radius: 32rpx;
.filter-text {
font-size: 26rpx;
color: #606266;
margin-right: 8rpx;
}
}
}
.list-wrap {
padding: 0 28rpx;
}
.approve-card {
background: #ffffff;
border-radius: 16rpx;
margin-bottom: 24rpx;
overflow: hidden;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
.card-title {
font-size: 30rpx;
font-weight: 600;
color: #1e293b;
padding: 24rpx 28rpx 12rpx;
}
.card-body {
padding: 0 28rpx 20rpx;
.card-row {
margin-bottom: 10rpx;
.card-label {
font-size: 26rpx;
color: #909399;
width: 160rpx;
flex-shrink: 0;
}
.card-value {
font-size: 26rpx;
color: #303133;
flex: 1;
word-break: break-all;
}
.card-time {
font-size: 24rpx;
color: #909399;
margin-left: 8rpx;
}
.card-tag {
font-size: 24rpx;
color: #e6a23c;
font-weight: 500;
}
}
}
.card-footer {
border-top: 1rpx solid #f0f1f5;
padding: 20rpx 28rpx;
.action-btn {
flex: 1;
text-align: center;
font-size: 28rpx;
font-weight: 500;
padding: 16rpx 0;
border-radius: 8rpx;
margin: 0 12rpx;
transition: all 0.2s ease;
&.reject {
color: #606266;
background: #f5f7fa;
border: 1rpx solid #dcdfe6;
&:active {
background: #e8eaed;
}
}
&.approve {
color: #3b82f6;
background: #ecf5ff;
border: 1rpx solid #b3d8ff;
&:active {
background: #d9ecff;
}
}
}
}
.card-status-bar {
border-top: 1rpx solid #f0f1f5;
padding: 20rpx 28rpx;
.status-text {
font-size: 26rpx;
font-weight: 500;
&.approved {
color: #3b82f6;
}
&.reviewing {
color: #3b82f6;
}
&.rejected {
color: #f56c6c;
}
}
}
}
}
...@@ -54,7 +54,6 @@ ...@@ -54,7 +54,6 @@
background: rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.2);
border-radius: 20rpx; border-radius: 20rpx;
transition: all 0.2s ease; transition: all 0.2s ease;
cursor: pointer;
&:active { &:active {
background: rgba(255, 255, 255, 0.35); background: rgba(255, 255, 255, 0.35);
...@@ -75,68 +74,49 @@ ...@@ -75,68 +74,49 @@
} }
} }
.fast-entry { .section-title {
position: relative; font-size: 30rpx;
background: #ffffff; font-weight: 600;
padding-top: 24rpx; color: #1e293b;
padding: 32rpx 28rpx 20rpx;
}
&::after { .entry-grid {
position: absolute; padding: 0 28rpx;
bottom: 0px;
left: 0; .entry-card {
right: 0; width: calc(50% - 12rpx);
width: 100%; margin-right: 24rpx;
height: 1px; margin-bottom: 24rpx;
background-color: #ffffff; padding: 28rpx 24rpx;
content: ''; background: #ffffff;
} border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
transition: all 0.2s ease;
.tit { &:nth-child(2n) {
font-size: 24rpx; margin-right: 0;
color: #1e2021; }
font-weight: bold;
margin-bottom: 36rpx;
padding-left: 24rpx;
}
.bar { &:active {
flex-wrap: wrap; transform: scale(0.97);
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
.box { }
position: relative;
flex: 1; .entry-icon {
height: 177rpx; width: 72rpx;
border-right: 1px solid #e6edf0; height: 72rpx;
border-bottom: 1px solid #e6edf0; background: #f0faf4;
border-radius: 16rpx;
&:nth-of-type(3n) { margin-right: 20rpx;
border-right: 1px solid transparent; flex-shrink: 0;
} }
.num { .entry-text {
position: absolute; font-size: 28rpx;
right: 32rpx; color: #1e293b;
top: 5rpx; font-weight: 500;
width: 42rpx;
height: 32rpx;
background: #bb3434;
border-radius: 16rpx;
font-size: 20rpx;
color: #ffffff;
}
.iconfont {
font-size: 64rpx;
color: #197adb;
}
.text {
margin-top: 8rpx;
font-size: 22rpx;
color: #404547;
}
} }
} }
} }
}
}
\ No newline at end of file
import App from './App' import App from './App'
import {request} from './util/util.js' import {request} from './util/util.js'
import uView from '@/uni_modules/uview-ui'
// #ifndef VUE3 // #ifndef VUE3
import Vue from 'vue' import Vue from 'vue'
Vue.use(uView)
Vue.config.productionTip = false; Vue.config.productionTip = false;
Vue.prototype.request = request; Vue.prototype.request = request;
App.mpType = 'app' App.mpType = 'app'
......
<template> <template>
<view class="apply-page"> <view class="apply-page">
<u-form :model="form" ref="formRef" labelWidth="180" labelPosition="left">
<view class="form-section">
<u-form-item label="申请类型" prop="applyType" required borderBottom
@click="showTypePicker = true">
<u--input v-model="form.applyTypeName" disabled disabledColor="#ffffff" placeholder="请选择"
border="none" inputAlign="right"></u--input>
<u-icon slot="right" name="arrow-down" color="#c0c4cc"></u-icon>
</u-form-item>
<u-form-item label="订单号" prop="orderNo" required borderBottom>
<u--input v-model="form.orderNo" placeholder="请输入" border="none" inputAlign="right"></u--input>
</u-form-item>
<u-form-item label="客户名称" prop="customerName" required borderBottom>
<view class="row verCenter boxFlex" style="justify-content: flex-end;">
<text class="link-text">关联订单号显示</text>
</view>
</u-form-item>
</view>
<view class="form-section">
<view class="section-header">费用明细</view>
<u-form-item label="申请免收金额" prop="amount" required borderBottom>
<u--input v-model="form.amount" placeholder="请输入" border="none" inputAlign="right"
type="number"></u--input>
</u-form-item>
<view class="currency-hint">
<text>CNY-人民币元</text>
</view>
<u-form-item label="减免明细(单选)" prop="deductionType" required borderBottom
@click="showDeductionPicker = true">
<u--input v-model="form.deductionTypeName" disabled disabledColor="#ffffff" placeholder="请选择"
border="none" inputAlign="right"></u--input>
<u-icon slot="right" name="arrow-down" color="#c0c4cc"></u-icon>
</u-form-item>
</view>
<view class="form-section">
<u-form-item label="免收原因" prop="reason" required labelPosition="top">
<u--textarea v-model="form.reason" placeholder="请输入" count maxlength="200"
autoHeight border="surround"></u--textarea>
</u-form-item>
</view>
</u-form>
<view class="error-tip row rowCenter verCenter" v-if="errorMsg">
<u-icon name="close-circle-fill" color="#f56c6c" size="32"></u-icon>
<text class="error-text">{{ errorMsg }}</text>
</view>
<view class="bottom-btn">
<u-button type="primary" shape="circle" text="提交" @click="handleSubmit"
:customStyle="{ background: 'linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)', height: '88rpx' }">
</u-button>
</view>
<u-action-sheet :show="showTypePicker" :actions="typeOptions" title="选择申请类型"
@close="showTypePicker = false" @select="onTypeSelect"></u-action-sheet>
<u-action-sheet :show="showDeductionPicker" :actions="deductionOptions" title="选择减免明细"
@close="showDeductionPicker = false" @select="onDeductionSelect"></u-action-sheet>
</view> </view>
</template> </template>
...@@ -9,12 +66,62 @@ ...@@ -9,12 +66,62 @@
export default { export default {
data() { data() {
return { return {
form: {
applyType: '',
applyTypeName: '',
orderNo: '',
customerName: '',
amount: '',
deductionType: '',
deductionTypeName: '',
reason: ''
},
errorMsg: '',
showTypePicker: false,
showDeductionPicker: false,
typeOptions: [
{ name: '费用减免申请', value: '1' }
],
deductionOptions: [
{ name: '代理费减免', value: '1' },
{ name: '标签操作费', value: '2' }
]
}; };
},
methods: {
/**
* 选择申请类型
* @param {Object} item - 选中项
* @return {void}
*/
onTypeSelect(item) {
this.form.applyType = item.value;
this.form.applyTypeName = item.name;
this.showTypePicker = false;
},
/**
* 选择减免明细
* @param {Object} item - 选中项
* @return {void}
*/
onDeductionSelect(item) {
this.form.deductionType = item.value;
this.form.deductionTypeName = item.name;
this.showDeductionPicker = false;
},
/**
* 提交申请
* @return {void}
*/
handleSubmit() {
// 后续接入接口逻辑
}
} }
}; };
</script> </script>
<style scoped lang="scss"> <style lang="scss">
@import '@/assets/css/apply/index.scss'; @import '@/assets/css/apply/index.scss';
</style> </style>
<template> <template>
<view class="approve-page"> <view class="approve-page">
<view class="search-bar">
<u-search v-model="keyword" :placeholder="currentTab === 0 ? '客户名称' : '申请内容'" shape="round"
:showAction="false" bgColor="#f5f7fa"></u-search>
</view>
<u-tabs :list="tabList" :current="currentTab" @click="onTabChange" lineColor="#3b82f6"
:activeStyle="{ color: '#3b82f6', fontWeight: '600' }"
:inactiveStyle="{ color: '#909399' }"></u-tabs>
<view class="filter-bar row verCenter">
<view class="filter-btn row verCenter" @click="showFilterPicker = true">
<text class="filter-text">{{ currentFilterName }}</text>
<u-icon name="arrow-down" color="#606266"></u-icon>
</view>
</view>
<!-- 待处理列表 -->
<view class="list-wrap" v-if="currentTab === 0">
<view class="approve-card" v-for="item in pendingList" :key="item.id">
<view class="card-title">{{ item.title }}</view>
<view class="card-body">
<view class="card-row row">
<text class="card-label">申请人:</text>
<text class="card-value">{{ item.applicant }}</text>
</view>
<view class="card-row row">
<text class="card-label">客户名称:</text>
<text class="card-value">{{ item.customerName }}</text>
</view>
<view class="card-row row">
<text class="card-label">订单号:</text>
<text class="card-value">{{ item.orderNo }}</text>
</view>
<view class="card-row row verCenter bothSide">
<view class="row verCenter">
<u-icon name="info-circle-fill" color="#3b82f6" size="28"></u-icon>
<text class="card-time">{{ item.time }}</text>
</view>
<text class="card-tag">{{ item.tag }}</text>
</view>
</view>
<view class="card-footer row rowCenter">
<view class="action-btn reject" @click="handleReject(item)">拒绝</view>
<view class="action-btn approve" @click="handleApprove(item)">同意</view>
</view>
</view>
<u-empty v-if="!pendingList.length" mode="data" text="暂无待处理审批"></u-empty>
</view>
<!-- 已处理列表 -->
<view class="list-wrap" v-if="currentTab === 1">
<view class="approve-card" v-for="item in doneList" :key="item.id">
<view class="card-title">{{ item.title }}</view>
<view class="card-body">
<view class="card-row row">
<text class="card-label">申请人:</text>
<text class="card-value">{{ item.applicant }}</text>
</view>
<view class="card-row row">
<text class="card-label">客户名称:</text>
<text class="card-value">{{ item.customerName }}</text>
</view>
<view class="card-row row">
<text class="card-label">订单号:</text>
<text class="card-value">{{ item.orderNo }}</text>
</view>
<view class="card-row row verCenter bothSide">
<view class="row verCenter">
<u-icon name="info-circle-fill" color="#3b82f6" size="28"></u-icon>
<text class="card-time">{{ item.time }}</text>
</view>
<text class="card-tag">{{ item.tag }}</text>
</view>
</view>
<view class="card-status-bar row rowCenter">
<text :class="['status-text', item.status === 'approved' ? 'approved' : item.status === 'reviewing' ? 'reviewing' : 'rejected']">
{{ item.statusText }}
</text>
</view>
</view>
<u-empty v-if="!doneList.length" mode="data" text="暂无已处理审批"></u-empty>
</view>
<u-action-sheet :show="showFilterPicker" :actions="filterOptions" title="筛选审批类型"
@close="showFilterPicker = false" @select="onFilterSelect"></u-action-sheet>
</view> </view>
</template> </template>
...@@ -8,15 +94,109 @@ ...@@ -8,15 +94,109 @@
export default { export default {
data() { data() {
return { return {
keyword: '',
currentTab: 0,
tabList: [
{ name: '待处理(2)' },
{ name: '已处理' }
],
showFilterPicker: false,
currentFilter: 'all',
currentFilterName: '全部审批',
filterOptions: [
{ name: '全部审批', value: 'all' },
{ name: '代理费减免', value: 'agent' },
{ name: '标签操作费', value: 'label' }
],
// 静态演示数据
pendingList: [
{
id: 1,
title: '费用减免申请',
applicant: '陈小将',
customerName: '深圳市海克斯科技有限公司',
orderNo: 'B123456',
time: '2026-04-10 14:01',
tag: '代理费减免'
},
{
id: 2,
title: '费用减免申请',
applicant: '$_发起人姓名',
customerName: '$_客户名称',
orderNo: '$_关联客户名称',
time: '2026-04-10 14:04',
tag: '代理费减免'
}
],
doneList: [
{
id: 3,
title: '客户费用减免申请',
applicant: '陈小将',
customerName: '深圳市海克斯科技有限公司',
orderNo: 'B123456',
time: '2026-04-10 14:01',
tag: '标签操作费',
status: 'reviewing',
statusText: '审批中'
},
{
id: 4,
title: '客户费用减免申请',
applicant: '陈小将',
customerName: '深圳市海克斯科技有限公司',
orderNo: 'B123456',
time: '2026-04-10 14:01',
tag: '标签操作费',
status: 'approved',
statusText: '已通过'
}
]
}; };
}, },
methods: { methods: {
/**
* Tab 切换
* @param {Object} item - 选中的 tab 项
* @return {void}
*/
onTabChange(item) {
this.currentTab = item.index;
},
/**
* 筛选选择
* @param {Object} item - 选中的筛选项
* @return {void}
*/
onFilterSelect(item) {
this.currentFilter = item.value;
this.currentFilterName = item.name;
this.showFilterPicker = false;
},
/**
* 拒绝审批
* @param {Object} item - 审批项
* @return {void}
*/
handleReject(item) {
// 后续接入接口逻辑
},
/**
* 同意审批
* @param {Object} item - 审批项
* @return {void}
*/
handleApprove(item) {
// 后续接入接口逻辑
}
} }
}; };
</script> </script>
<style scoped lang="scss"> <style lang="scss">
@import '@/assets/css/approve/index.scss'; @import '@/assets/css/approve/index.scss';
</style> </style>
<template> <template>
<view class="home-index"> <view class="home-index">
<!-- 实际内容 -->
<view class="head" v-if="!loading && info.user_info"> <view class="head" v-if="!loading && info.user_info">
<view class=" row bothSide verCenter"> <view class="row bothSide verCenter">
<view class="info-bar row verCenter"> <view class="info-bar row verCenter">
<text class="iconfont icon-juxing"></text> <text class="iconfont icon-juxing"></text>
<view class="column"> <view class="column">
...@@ -17,6 +16,16 @@ ...@@ -17,6 +16,16 @@
</view> </view>
</view> </view>
<view class="section-title">审批</view>
<view class="entry-grid row" style="flex-wrap: wrap;">
<view class="entry-card row verCenter" v-for="item in entryList" :key="item.id" @click="goApply(item)">
<view class="entry-icon row rowCenter verCenter">
<u-icon name="plus-circle-fill" color="#19be6b" size="44"></u-icon>
</view>
<text class="entry-text">{{ item.name }}</text>
</view>
</view>
</view> </view>
</template> </template>
...@@ -27,7 +36,10 @@ ...@@ -27,7 +36,10 @@
data() { data() {
return { return {
info: {}, info: {},
loading: true loading: true,
entryList: [
{ id: 1, name: '费用减免申请' }
]
}; };
}, },
onShow() { onShow() {
...@@ -36,6 +48,7 @@ ...@@ -36,6 +48,7 @@
methods: { methods: {
/** /**
* 获取数据 * 获取数据
* @return {void}
*/ */
getData() { getData() {
this.request(API.getStatisticsInfo, 'POST', {}, false).then(res => { this.request(API.getStatisticsInfo, 'POST', {}, false).then(res => {
...@@ -47,8 +60,21 @@ ...@@ -47,8 +60,21 @@
this.loading = false; this.loading = false;
}); });
}, },
/**
* 跳转到发起申请页
* @param {Object} item - 入口项
* @return {void}
*/
goApply(item) {
uni.switchTab({
url: '/pages/apply/index'
});
},
/** /**
* 退出系统 * 退出系统
* @return {void}
*/ */
exit() { exit() {
uni.showModal({ uni.showModal({
...@@ -57,14 +83,10 @@ ...@@ -57,14 +83,10 @@
showCancel: true, showCancel: true,
success: res => { success: res => {
if (res.confirm) { if (res.confirm) {
// 批量清理用户相关存储
['oa_skey', 'oa_user_id', 'email', 'user_name'].map(key => uni.removeStorageSync(key)); ['oa_skey', 'oa_user_id', 'email', 'user_name'].map(key => uni.removeStorageSync(key));
uni.redirectTo({ uni.redirectTo({
url: '/pages/mine/login' url: '/pages/mine/login'
}); });
} else if (res.cancel) {
// 用户点击取消操作
console.log('用户点击取消');
} }
} }
}); });
......
@import '@/uni_modules/uview-ui/theme.scss';
/* 行为相关颜色 */ /* 行为相关颜色 */
$uni-color-primary: #197adb; $uni-color-primary: #197adb;
$uni-color-success: #4cd964; $uni-color-success: #4cd964;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment