|
|
<template>
|
|
|
<z-paging ref="paging" v-model="receiptRecords" @query="queryList" :layout-only="activeTab === 'form'">
|
|
|
<template #top>
|
|
|
<!-- 顶部标签:我要领用 / 领用记录 -->
|
|
|
<view class="tabs">
|
|
|
<view
|
|
|
class="tab"
|
|
|
:class="activeTab === 'form' ? 'active' : ''"
|
|
|
@click="activeTab = 'form'"
|
|
|
>
|
|
|
我要领用
|
|
|
</view>
|
|
|
<view
|
|
|
class="tab"
|
|
|
:class="activeTab === 'list' ? 'active' : ''"
|
|
|
@click="switchToList"
|
|
|
>
|
|
|
领用记录
|
|
|
</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<!-- 表单区域 -->
|
|
|
<view class="tab-content" v-show="activeTab === 'form'">
|
|
|
<view class="form-card">
|
|
|
<view class="form-item">
|
|
|
<text class="label">物资选择</text>
|
|
|
<view class="multi-select">
|
|
|
<view class="selected-items" v-if="selectedMaterials.length > 0">
|
|
|
<view class="selected-item" v-for="(item, index) in selectedMaterials" :key="item.cargoId">
|
|
|
<text>{{ item.cargoName }} ({{ item.cargoSpec }}) x {{ item.quantity }}</text>
|
|
|
<text class="remove-btn" @click="removeMaterial(index)">x</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="select-btn" @click="showMaterialSelector">
|
|
|
{{ selectedMaterials.length > 0 ? '已选择 ' + selectedMaterials.length + ' 项' : '请选择物资' }}
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="form-item">
|
|
|
<text class="label">领用用途</text>
|
|
|
<textarea
|
|
|
class="textarea"
|
|
|
v-model="receiptForm.purpose"
|
|
|
placeholder="请输入领用用途"
|
|
|
maxlength="200"
|
|
|
:auto-height="true"
|
|
|
/>
|
|
|
<text class="count">{{ receiptForm.purpose.length }}/200</text>
|
|
|
</view>
|
|
|
|
|
|
<!-- <view class="form-item">
|
|
|
<text class="label">领用人</text>
|
|
|
<input
|
|
|
class="input"
|
|
|
type="text"
|
|
|
v-model="receiptForm.applicant"
|
|
|
placeholder="请输入领用人姓名"
|
|
|
/>
|
|
|
</view> -->
|
|
|
</view>
|
|
|
|
|
|
<view class="submit-section">
|
|
|
<view class="submit-btn" @click="submitReceipt">提交领用申请</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 物资选择弹窗 -->
|
|
|
<uni-popup ref="materialPopup" type="bottom" :animation="false">
|
|
|
<view class="popup-content">
|
|
|
<view class="popup-header">
|
|
|
<text class="popup-title">选择物资</text>
|
|
|
<text class="popup-close" @click="closeMaterialSelector">×</text>
|
|
|
</view>
|
|
|
<view class="popup-body">
|
|
|
<view class="search-box">
|
|
|
<input type="text" v-model="searchKeyword" placeholder="搜索物资名称或规格" class="search-input" />
|
|
|
</view>
|
|
|
<view class="material-list">
|
|
|
<view
|
|
|
class="material-item"
|
|
|
v-for="material in filteredMaterials"
|
|
|
:key="material.cargoId"
|
|
|
>
|
|
|
<view class="material-info">
|
|
|
<text class="material-name">{{ material.cargoName }}</text>
|
|
|
<text class="material-spec">{{ material.cargoSpec }}</text>
|
|
|
</view>
|
|
|
<view class="item-actions">
|
|
|
<view v-if="isMaterialSelected(material.cargoId)" class="quantity-input">
|
|
|
<text class="quantity-btn" @click="decreaseQuantity(material.cargoId)">-</text>
|
|
|
<input
|
|
|
type="number"
|
|
|
:value="getMaterialQuantity(material.cargoId)"
|
|
|
class="quantity-input-box"
|
|
|
min="1"
|
|
|
@input="updateQuantity(material.cargoId, $event)"
|
|
|
/>
|
|
|
<text class="quantity-btn" @click="increaseQuantity(material.cargoId)">+</text>
|
|
|
</view>
|
|
|
<view class="checkbox" :class="{ checked: isMaterialSelected(material.cargoId) }" @click="toggleMaterial(material)">
|
|
|
<text v-if="isMaterialSelected(material.cargoId)">✓</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="popup-footer">
|
|
|
<view class="footer-btn cancel" @click="closeMaterialSelector">取消</view>
|
|
|
<view class="footer-btn confirm" @click="confirmMaterialSelection">确定</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</uni-popup>
|
|
|
|
|
|
<!-- 列表区域 -->
|
|
|
<view class="tab-content" v-show="activeTab === 'list'">
|
|
|
<view
|
|
|
class="record-card"
|
|
|
v-for="item in receiptRecords"
|
|
|
:key="item.id"
|
|
|
>
|
|
|
<view class="card-header">
|
|
|
<view class="left">
|
|
|
<text class="type">领用单</text>
|
|
|
<text
|
|
|
class="status"
|
|
|
:class="{
|
|
|
'status-pending': getStatusText(item) === '待审批',
|
|
|
'status-approved': getStatusText(item) === '已审批',
|
|
|
'status-rejected': getStatusText(item) === '已拒绝',
|
|
|
'status-canceled': getStatusText(item) === '已取消',
|
|
|
'status-verified': getStatusText(item) === '已核销'
|
|
|
}"
|
|
|
>
|
|
|
{{ getStatusText(item) }}
|
|
|
</text>
|
|
|
</view>
|
|
|
<view class="header-right">
|
|
|
<text class="time">
|
|
|
{{ item.billDate || '' }}
|
|
|
</text>
|
|
|
<text class="bill-number">
|
|
|
{{ item.billNumber || '' }}
|
|
|
</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="card-body">
|
|
|
<view class="row">
|
|
|
<text class="label">领用用途</text>
|
|
|
<text class="value">
|
|
|
{{ item.remark || '—' }}
|
|
|
</text>
|
|
|
</view>
|
|
|
<!-- <view class="row">
|
|
|
<text class="label">领用部门</text>
|
|
|
<text class="value">
|
|
|
{{ item.ckBillCargos && item.ckBillCargos.length > 0 ? (item.ckBillCargos[0].receiveDeptName || '—') : '—' }}
|
|
|
</text>
|
|
|
</view>
|
|
|
<view class="row">
|
|
|
<text class="label">领用人</text>
|
|
|
<text class="value">
|
|
|
{{ item.ckBillCargos && item.ckBillCargos.length > 0 ? (item.ckBillCargos[0].receiverName || '—') : '—' }}
|
|
|
</text>
|
|
|
</view> -->
|
|
|
<view class="row" v-if="item.ckBillCargos && item.ckBillCargos.length > 0">
|
|
|
<text class="label">领用物资</text>
|
|
|
<text class="value">
|
|
|
<text v-for="(cargo, index) in item.ckBillCargos" :key="cargo.id">
|
|
|
{{ cargo.cargoName }}{{ cargo.cargoSpec ? ` (${cargo.cargoSpec})` : '' }}{{ cargo.cargoWt ? ` x ${parseFloat(cargo.cargoWt).toFixed(2).replace(/\.?0+$/, '')}` : '' }}{{ index < item.ckBillCargos.length - 1 ? '、' : '' }}
|
|
|
</text>
|
|
|
</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="card-footer">
|
|
|
<view class="action-buttons">
|
|
|
<view class="action-btn cancel-btn" v-if="item.cancelStatus === '0' && item.billStatus === '0'" @click="cancelBill(item.id)">取消单据</view>
|
|
|
<view class="action-btn voucher-btn" v-if="item.auditStatus === '1' && item.billStatus === '0'" @click="viewVoucher(item)">查看凭证</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 凭证弹窗 -->
|
|
|
<uni-popup ref="voucherPopup" type="center" :animation="false">
|
|
|
<view class="voucher-popup">
|
|
|
<view class="voucher-header">
|
|
|
<text class="voucher-title">领用凭证</text>
|
|
|
<text class="voucher-close" @click="closeVoucherPopup">×</text>
|
|
|
</view>
|
|
|
<view class="voucher-body">
|
|
|
<view class="voucher-info">
|
|
|
<text class="voucher-label">单据编号</text>
|
|
|
<text class="voucher-value">{{ currentVoucher ? currentVoucher.billNumber : '' }}</text>
|
|
|
</view>
|
|
|
<view class="qrcode-container">
|
|
|
<canvas canvas-id="qrcode" :style="{width: `${qrcodeSize}px`, height: `${qrcodeSize}px`}" />
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="voucher-footer">
|
|
|
<view class="footer-btn confirm" @click="closeVoucherPopup">确定</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</uni-popup>
|
|
|
</z-paging>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import uQRCode from '@/js_sdk/Sansnn-uQRCode/uqrcode.js';
|
|
|
import { listCkstock, quickOutBill, stockPageList, cancelBill } from '@/api/property.js';
|
|
|
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
activeTab: 'form',
|
|
|
receiptForm: {
|
|
|
purpose: '',
|
|
|
applicant: ''
|
|
|
},
|
|
|
statusClassMap: {
|
|
|
'待审批': 'status-pending',
|
|
|
'已审批': 'status-approved',
|
|
|
'已拒绝': 'status-rejected',
|
|
|
'已取消': 'status-canceled',
|
|
|
'已核销': 'status-verified',
|
|
|
'__default__': 'status-pending'
|
|
|
},
|
|
|
materials: [],
|
|
|
selectedMaterials: [],
|
|
|
searchKeyword: '',
|
|
|
tempSelectedMaterials: [],
|
|
|
receiptRecords: [],
|
|
|
currentVoucher: null,
|
|
|
qrcodeSize: 200
|
|
|
};
|
|
|
},
|
|
|
onLoad() {
|
|
|
if (this.activeTab === 'list') {
|
|
|
this.refreshList();
|
|
|
}
|
|
|
},
|
|
|
onShow() {
|
|
|
// 页面显示时获取物资列表
|
|
|
this.getMaterialsList();
|
|
|
},
|
|
|
computed: {
|
|
|
filteredMaterials() {
|
|
|
if (!this.searchKeyword) {
|
|
|
return this.materials;
|
|
|
}
|
|
|
return this.materials.filter(item =>
|
|
|
item.cargoName.includes(this.searchKeyword) ||
|
|
|
item.cargoSpec.includes(this.searchKeyword)
|
|
|
);
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
switchToList() {
|
|
|
this.activeTab = 'list';
|
|
|
if (!this.receiptRecords.length) {
|
|
|
this.$refs.paging.reload();
|
|
|
}
|
|
|
},
|
|
|
// 获取物资列表
|
|
|
getMaterialsList() {
|
|
|
listCkstock().then(res => {
|
|
|
if (res.code === 200) {
|
|
|
this.materials = res.data;
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
// 显示物资选择器
|
|
|
showMaterialSelector() {
|
|
|
// 重置临时选择列表
|
|
|
this.tempSelectedMaterials = [...this.selectedMaterials];
|
|
|
this.searchKeyword = '';
|
|
|
// 打开弹窗
|
|
|
this.$refs.materialPopup.open();
|
|
|
},
|
|
|
// 关闭物资选择器
|
|
|
closeMaterialSelector() {
|
|
|
this.$refs.materialPopup.close();
|
|
|
},
|
|
|
// 切换物资选择状态
|
|
|
toggleMaterial(material) {
|
|
|
const index = this.tempSelectedMaterials.findIndex(item => item.cargoId === material.cargoId);
|
|
|
if (index > -1) {
|
|
|
this.tempSelectedMaterials.splice(index, 1);
|
|
|
} else {
|
|
|
// 添加数量字段
|
|
|
this.tempSelectedMaterials.push({ ...material, quantity: 1 });
|
|
|
}
|
|
|
},
|
|
|
// 检查物资是否已选择
|
|
|
isMaterialSelected(cargoId) {
|
|
|
return this.tempSelectedMaterials.some(item => item.cargoId === cargoId);
|
|
|
},
|
|
|
// 获取物资数量
|
|
|
getMaterialQuantity(cargoId) {
|
|
|
const item = this.tempSelectedMaterials.find(item => item.cargoId === cargoId);
|
|
|
return item ? item.quantity : 1;
|
|
|
},
|
|
|
// 增加数量
|
|
|
increaseQuantity(cargoId) {
|
|
|
const item = this.tempSelectedMaterials.find(item => item.cargoId === cargoId);
|
|
|
if (item) {
|
|
|
item.quantity += 1;
|
|
|
}
|
|
|
},
|
|
|
// 减少数量
|
|
|
decreaseQuantity(cargoId) {
|
|
|
const item = this.tempSelectedMaterials.find(item => item.cargoId === cargoId);
|
|
|
if (item && item.quantity > 1) {
|
|
|
item.quantity -= 1;
|
|
|
}
|
|
|
},
|
|
|
// 更新数量
|
|
|
updateQuantity(cargoId, event) {
|
|
|
const item = this.tempSelectedMaterials.find(item => item.cargoId === cargoId);
|
|
|
if (item) {
|
|
|
const value = parseInt(event.target.value) || 1;
|
|
|
item.quantity = Math.max(1, value);
|
|
|
}
|
|
|
},
|
|
|
// 确认物资选择
|
|
|
confirmMaterialSelection() {
|
|
|
this.selectedMaterials = [...this.tempSelectedMaterials];
|
|
|
this.closeMaterialSelector();
|
|
|
},
|
|
|
// 移除已选物资
|
|
|
removeMaterial(index) {
|
|
|
this.selectedMaterials.splice(index, 1);
|
|
|
},
|
|
|
submitReceipt() {
|
|
|
if (this.selectedMaterials.length === 0 || !this.receiptForm.purpose) {
|
|
|
uni.showToast({
|
|
|
title: '请填写完整信息',
|
|
|
icon: 'none'
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 准备提交数据
|
|
|
const items = this.selectedMaterials.map(item => ({
|
|
|
cargoId: item.cargoId,
|
|
|
quantity: item.quantity,
|
|
|
billNumber: item.billNumber,
|
|
|
stockId: item.stockId,
|
|
|
stockCode: item.stockCode,
|
|
|
ckCargoStockId: item.id,
|
|
|
}));
|
|
|
|
|
|
const submitData = {
|
|
|
purpose: this.receiptForm.purpose,
|
|
|
items: items
|
|
|
};
|
|
|
uni.showLoading({
|
|
|
title: '提交中...'
|
|
|
});
|
|
|
|
|
|
// 调用接口提交领用申请
|
|
|
quickOutBill(submitData).then(res => {
|
|
|
uni.hideLoading();
|
|
|
if (res.code === 200) {
|
|
|
uni.showToast({
|
|
|
title: '领用申请提交成功',
|
|
|
icon: 'success'
|
|
|
});
|
|
|
|
|
|
// 重置表单
|
|
|
setTimeout(() => {
|
|
|
this.receiptForm = {
|
|
|
purpose: '',
|
|
|
applicant: ''
|
|
|
};
|
|
|
this.selectedMaterials = [];
|
|
|
},
|
|
|
1500);
|
|
|
|
|
|
// 如果当前在列表页,刷新列表
|
|
|
if (this.activeTab === 'list') {
|
|
|
this.$refs.paging.reload();
|
|
|
}
|
|
|
} else {
|
|
|
uni.showToast({
|
|
|
title: res.message || '提交失败',
|
|
|
icon: 'none'
|
|
|
});
|
|
|
}
|
|
|
}).catch(() => {
|
|
|
uni.hideLoading();
|
|
|
});
|
|
|
},
|
|
|
// 获取状态文本
|
|
|
getStatusText(item) {
|
|
|
if (item.billStatus === '1') {
|
|
|
return '已核销';
|
|
|
}
|
|
|
if (item.cancelStatus === '1') {
|
|
|
return '已取消';
|
|
|
}
|
|
|
switch (item.auditStatus) {
|
|
|
case '0':
|
|
|
return '待审批';
|
|
|
case '1':
|
|
|
return '已审批';
|
|
|
case '2':
|
|
|
return '已拒绝';
|
|
|
default:
|
|
|
return '待审批';
|
|
|
}
|
|
|
},
|
|
|
// 获取状态样式
|
|
|
getStatusClass(item) {
|
|
|
const statusText = this.getStatusText(item);
|
|
|
return this.statusClassMap[statusText] || this.statusClassMap['__default__'];
|
|
|
},
|
|
|
// 取消单据
|
|
|
cancelBill(id) {
|
|
|
uni.showModal({
|
|
|
title: '取消单据',
|
|
|
content: '确定要取消此单据吗?',
|
|
|
confirmText: '确定',
|
|
|
cancelText: '取消',
|
|
|
success: (res) => {
|
|
|
if (res.confirm) {
|
|
|
cancelBill(id).then(response => {
|
|
|
if (response.code === 200) {
|
|
|
uni.showToast({
|
|
|
title: '单据取消成功',
|
|
|
icon: 'success'
|
|
|
});
|
|
|
// 刷新列表
|
|
|
this.$refs.paging.reload();
|
|
|
} else {
|
|
|
uni.showToast({
|
|
|
title: response.message || '取消失败',
|
|
|
icon: 'none'
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
// 查看凭证
|
|
|
viewVoucher(item) {
|
|
|
this.currentVoucher = item;
|
|
|
// 打开弹窗
|
|
|
this.$refs.voucherPopup.open();
|
|
|
// 生成二维码
|
|
|
this.generateQRCode(item.billNumber);
|
|
|
},
|
|
|
// 关闭凭证弹窗
|
|
|
closeVoucherPopup() {
|
|
|
this.$refs.voucherPopup.close();
|
|
|
},
|
|
|
// 生成二维码
|
|
|
generateQRCode(billNumber) {
|
|
|
console.log('开始生成二维码');
|
|
|
uQRCode.make({
|
|
|
canvasId: 'qrcode',
|
|
|
text: billNumber,
|
|
|
size: this.qrcodeSize,
|
|
|
margin: 10,
|
|
|
success: res => {
|
|
|
console.log(res);
|
|
|
},
|
|
|
complete: () => {
|
|
|
},
|
|
|
fail: res => {
|
|
|
console.log(res);
|
|
|
uni.showToast({
|
|
|
title: '二维码生成失败',
|
|
|
icon: 'none'
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
// 获取领用记录列表
|
|
|
queryList(pageNo, pageSize) {
|
|
|
stockPageList({ page: pageNo, limit: pageSize, billType: 2 }).then(res => {
|
|
|
if (res.code === 200) {
|
|
|
const list = res.data.list;
|
|
|
// 将请求结果通过complete传给z-paging处理
|
|
|
this.$refs.paging.complete(list);
|
|
|
} else {
|
|
|
this.$refs.paging.complete([]);
|
|
|
}
|
|
|
}).catch(e => {
|
|
|
this.$refs.paging.complete(false);
|
|
|
});
|
|
|
},
|
|
|
refreshList() {
|
|
|
if (this.$refs.paging) {
|
|
|
this.$refs.paging.reload();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
.tabs {
|
|
|
padding: 0 30rpx;
|
|
|
display: flex;
|
|
|
margin-bottom: 15rpx;
|
|
|
background-color: #fff;
|
|
|
border-radius: 10rpx;
|
|
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
.tab {
|
|
|
flex: 1;
|
|
|
height: 80rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
font-size: 26rpx;
|
|
|
color: #666;
|
|
|
position: relative;
|
|
|
|
|
|
&.active {
|
|
|
color: #409EFF;
|
|
|
|
|
|
&::after {
|
|
|
content: '';
|
|
|
position: absolute;
|
|
|
bottom: 0;
|
|
|
left: 50%;
|
|
|
transform: translateX(-50%);
|
|
|
width: 60rpx;
|
|
|
height: 4rpx;
|
|
|
background-color: #409EFF;
|
|
|
border-radius: 2rpx;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.tab-content {
|
|
|
padding: 0 30rpx;
|
|
|
|
|
|
.form-card {
|
|
|
background-color: #fff;
|
|
|
border-radius: 10rpx;
|
|
|
padding: 30rpx;
|
|
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.08);
|
|
|
|
|
|
.form-item {
|
|
|
margin-bottom: 30rpx;
|
|
|
|
|
|
.label {
|
|
|
display: block;
|
|
|
font-size: 26rpx;
|
|
|
color: #333;
|
|
|
margin-bottom: 16rpx;
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
|
|
|
.input {
|
|
|
width: 100%;
|
|
|
height: 72rpx;
|
|
|
border-radius: 10rpx;
|
|
|
border: 1rpx solid #e5e5e5;
|
|
|
padding: 0 20rpx;
|
|
|
font-size: 24rpx;
|
|
|
box-sizing: border-box;
|
|
|
}
|
|
|
|
|
|
.textarea {
|
|
|
width: 100%;
|
|
|
min-height: 160rpx;
|
|
|
border-radius: 10rpx;
|
|
|
border: 1rpx solid #e5e5e5;
|
|
|
padding: 20rpx;
|
|
|
font-size: 24rpx;
|
|
|
box-sizing: border-box;
|
|
|
line-height: 1.6;
|
|
|
}
|
|
|
|
|
|
.count {
|
|
|
display: block;
|
|
|
margin-top: 10rpx;
|
|
|
text-align: right;
|
|
|
font-size: 20rpx;
|
|
|
color: #999;
|
|
|
}
|
|
|
|
|
|
.multi-select {
|
|
|
.selected-items {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
gap: 12rpx;
|
|
|
margin-bottom: 12rpx;
|
|
|
|
|
|
.selected-item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
background-color: #f0f9ff;
|
|
|
border: 1rpx solid #e6f7ff;
|
|
|
border-radius: 16rpx;
|
|
|
padding: 8rpx 16rpx;
|
|
|
font-size: 22rpx;
|
|
|
color: #409EFF;
|
|
|
|
|
|
.remove-btn {
|
|
|
margin-left: 8rpx;
|
|
|
font-size: 24rpx;
|
|
|
font-weight: bold;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.select-btn {
|
|
|
width: 100%;
|
|
|
height: 72rpx;
|
|
|
border-radius: 10rpx;
|
|
|
border: 1rpx solid #e5e5e5;
|
|
|
padding: 0 20rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
font-size: 24rpx;
|
|
|
color: #999;
|
|
|
box-sizing: border-box;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.submit-section {
|
|
|
margin-top: 40rpx;
|
|
|
margin-bottom: 30rpx;
|
|
|
|
|
|
.submit-btn {
|
|
|
height: 88rpx;
|
|
|
background-color: #409EFF;
|
|
|
color: #fff;
|
|
|
border-radius: 44rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
font-size: 30rpx;
|
|
|
font-weight: 600;
|
|
|
box-shadow: 0 4rpx 12rpx rgba(64, 158, 255, 0.35);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.record-card {
|
|
|
background-color: #fff;
|
|
|
border-radius: 10rpx;
|
|
|
padding: 24rpx 26rpx;
|
|
|
margin-bottom: 20rpx;
|
|
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.06);
|
|
|
|
|
|
.card-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
|
margin-bottom: 16rpx;
|
|
|
|
|
|
.left {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
.type {
|
|
|
font-size: 26rpx;
|
|
|
font-weight: 600;
|
|
|
color: #333;
|
|
|
margin-right: 16rpx;
|
|
|
}
|
|
|
|
|
|
.status {
|
|
|
padding: 6rpx 18rpx;
|
|
|
border-radius: 20rpx;
|
|
|
font-size: 20rpx;
|
|
|
}
|
|
|
|
|
|
.status-pending {
|
|
|
background-color: #E6F7FF;
|
|
|
color: #409EFF;
|
|
|
}
|
|
|
|
|
|
.status-approved {
|
|
|
background-color: #F6FFED;
|
|
|
color: #52C41A;
|
|
|
}
|
|
|
|
|
|
.status-rejected {
|
|
|
background-color: #FFF1F0;
|
|
|
color: #FF4D4F;
|
|
|
}
|
|
|
|
|
|
.status-canceled {
|
|
|
background-color: #F5F5F5;
|
|
|
color: #999;
|
|
|
}
|
|
|
|
|
|
.status-verified {
|
|
|
background-color: #E8F5E8;
|
|
|
color: #4CAF50;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.header-right {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
flex-direction: column;
|
|
|
align-items: flex-end;
|
|
|
|
|
|
.time {
|
|
|
font-size: 22rpx;
|
|
|
color: #999;
|
|
|
margin-bottom: 8rpx;
|
|
|
}
|
|
|
|
|
|
.bill-number {
|
|
|
font-size: 20rpx;
|
|
|
color: #666;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.card-body {
|
|
|
.row {
|
|
|
display: flex;
|
|
|
margin-bottom: 10rpx;
|
|
|
|
|
|
.label {
|
|
|
width: 140rpx;
|
|
|
font-size: 24rpx;
|
|
|
color: #666;
|
|
|
}
|
|
|
|
|
|
.value {
|
|
|
flex: 1;
|
|
|
font-size: 24rpx;
|
|
|
color: #333;
|
|
|
word-break: break-word;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.card-footer {
|
|
|
margin-top: 16rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
.action-buttons {
|
|
|
display: flex;
|
|
|
gap: 16rpx;
|
|
|
|
|
|
.action-btn {
|
|
|
padding: 8rpx 24rpx;
|
|
|
border-radius: 16rpx;
|
|
|
font-size: 22rpx;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
.cancel-btn {
|
|
|
background-color: #F5F5F5;
|
|
|
color: #666;
|
|
|
}
|
|
|
|
|
|
.voucher-btn {
|
|
|
background-color: #409EFF;
|
|
|
color: #fff;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 弹窗样式 */
|
|
|
.popup-content {
|
|
|
background-color: #fff;
|
|
|
border-top-left-radius: 20rpx;
|
|
|
border-top-right-radius: 20rpx;
|
|
|
padding-bottom: 30rpx;
|
|
|
|
|
|
.popup-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
|
padding: 30rpx;
|
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
|
|
.popup-title {
|
|
|
font-size: 28rpx;
|
|
|
font-weight: 600;
|
|
|
color: #333;
|
|
|
}
|
|
|
|
|
|
.popup-close {
|
|
|
font-size: 36rpx;
|
|
|
color: #999;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.popup-body {
|
|
|
max-height: 60vh;
|
|
|
overflow-y: auto;
|
|
|
|
|
|
.search-box {
|
|
|
padding: 20rpx 30rpx;
|
|
|
|
|
|
.search-input {
|
|
|
width: 100%;
|
|
|
height: 64rpx;
|
|
|
border-radius: 32rpx;
|
|
|
border: 1rpx solid #e5e5e5;
|
|
|
padding: 0 24rpx;
|
|
|
font-size: 24rpx;
|
|
|
box-sizing: border-box;
|
|
|
background-color: #f9f9f9;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.material-list {
|
|
|
.material-item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
|
padding: 24rpx 30rpx;
|
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
|
|
.material-info {
|
|
|
flex: 1;
|
|
|
|
|
|
.material-name {
|
|
|
display: block;
|
|
|
font-size: 26rpx;
|
|
|
color: #333;
|
|
|
margin-bottom: 8rpx;
|
|
|
}
|
|
|
|
|
|
.material-spec {
|
|
|
font-size: 22rpx;
|
|
|
color: #999;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.item-actions {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 20rpx;
|
|
|
|
|
|
.quantity-input {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
border: 1rpx solid #e5e5e5;
|
|
|
border-radius: 8rpx;
|
|
|
|
|
|
.quantity-btn {
|
|
|
width: 40rpx;
|
|
|
height: 40rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
font-size: 24rpx;
|
|
|
color: #666;
|
|
|
background-color: #f5f5f5;
|
|
|
}
|
|
|
|
|
|
.quantity-input-box {
|
|
|
width: 80rpx;
|
|
|
height: 40rpx;
|
|
|
border: none;
|
|
|
text-align: center;
|
|
|
font-size: 22rpx;
|
|
|
color: #333;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.checkbox {
|
|
|
width: 36rpx;
|
|
|
height: 36rpx;
|
|
|
border: 2rpx solid #e5e5e5;
|
|
|
border-radius: 50%;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
font-size: 24rpx;
|
|
|
color: #fff;
|
|
|
cursor: pointer;
|
|
|
|
|
|
&.checked {
|
|
|
background-color: #409EFF;
|
|
|
border-color: #409EFF;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.popup-footer {
|
|
|
display: flex;
|
|
|
padding: 20rpx 30rpx 0;
|
|
|
gap: 20rpx;
|
|
|
|
|
|
.footer-btn {
|
|
|
flex: 1;
|
|
|
height: 72rpx;
|
|
|
border-radius: 36rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
font-size: 26rpx;
|
|
|
font-weight: 600;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
.cancel {
|
|
|
background-color: #f5f5f5;
|
|
|
color: #666;
|
|
|
}
|
|
|
|
|
|
.confirm {
|
|
|
background-color: #409EFF;
|
|
|
color: #fff;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 凭证弹窗样式 */
|
|
|
.voucher-popup {
|
|
|
width: 680rpx;
|
|
|
background-color: #fff;
|
|
|
border-radius: 20rpx;
|
|
|
overflow: hidden;
|
|
|
|
|
|
.voucher-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
|
padding: 30rpx;
|
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
|
|
.voucher-title {
|
|
|
font-size: 28rpx;
|
|
|
font-weight: 600;
|
|
|
color: #333;
|
|
|
}
|
|
|
|
|
|
.voucher-close {
|
|
|
font-size: 36rpx;
|
|
|
color: #999;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.voucher-body {
|
|
|
padding: 40rpx 30rpx;
|
|
|
text-align: center;
|
|
|
|
|
|
.voucher-info {
|
|
|
margin-bottom: 30rpx;
|
|
|
|
|
|
.voucher-label {
|
|
|
display: block;
|
|
|
font-size: 24rpx;
|
|
|
color: #666;
|
|
|
margin-bottom: 12rpx;
|
|
|
}
|
|
|
|
|
|
.voucher-value {
|
|
|
font-size: 28rpx;
|
|
|
font-weight: 600;
|
|
|
color: #333;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.qrcode-container {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
margin: 0 auto;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.voucher-footer {
|
|
|
padding: 0 30rpx 30rpx;
|
|
|
|
|
|
.footer-btn {
|
|
|
width: 100%;
|
|
|
height: 72rpx;
|
|
|
border-radius: 36rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
font-size: 26rpx;
|
|
|
font-weight: 600;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
.confirm {
|
|
|
background-color: #409EFF;
|
|
|
color: #fff;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</style> |