buddhism/pages/memorial/addMemorial.vue

570 lines
12 KiB
Vue
Raw Normal View History

2025-10-16 17:34:44 +08:00
<template>
<view class="page">
<base-background />
<!-- 使用自定义导航栏组件 -->
<custom-navbar title="添加牌位" />
<view class="content">
<!-- 扫码获取SN和MAC -->
<view class="scan-section">
<view class="section-title">设备信息</view>
<view class="scan-container">
<view class="scan-btn" @click="handleScanCode">
<view class="qrcode-icon">
<image
mode="aspectFit"
src="https://api.ccttiot.com/smartmeter/img/static/uy7BNwAMIKwvstqFnRhs"
/>
</view>
<view class="scan-text">扫码获取设备信息</view>
</view>
</view>
<!-- 显示SN和MAC信息 -->
<view v-if="deviceInfo.sn || deviceInfo.mac" class="device-info">
<view v-if="deviceInfo.name" class="info-item">
<view class="info-label">设备名称</view>
<view class="info-value">{{ deviceInfo.name }}</view>
</view>
</view>
</view>
<!-- 牌位信息表单 -->
<view class="form-section">
<view class="section-title">牌位信息</view>
<view class="form-container">
<!-- 牌位编号 -->
<view class="form-item">
<view class="label"
>牌位编号
<text class="required">*</text>
</view>
<input
v-model="formData.code"
class="input"
maxlength="20"
placeholder="请输入牌位编号"
/>
</view>
<!-- 区域选择 -->
<view class="form-item">
<view class="label"
>所属区域
<text class="required">*</text>
</view>
<picker
:range="regionOptions"
:value="regionIndex"
class="picker"
@change="onRegionChange"
>
<view class="picker-text">
{{ regionOptions[regionIndex] || "请选择区域" }}
</view>
</picker>
</view>
</view>
</view>
<!-- 操作按钮 -->
<view class="button-container">
<view class="btn cancel-btn" @click="handleCancel">取消</view>
<view
:class="{ disabled: !canSubmit }"
class="btn confirm-btn"
@click="handleConfirm"
>确认添加
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
// 设备信息
deviceInfo: {
sn: "",
mac: "",
name: "",
id: "",
},
// 表单数据
formData: {
code: "",
name: "",
regionId: "",
orderNum: "",
remark: "",
},
// 区域选项
regionOptions: ["A区", "B区", "C区", "D区"],
regionIndex: -1,
// 加载状态
loading: false,
};
},
computed: {
// 是否可以提交
canSubmit() {
return (
this.deviceInfo.sn &&
this.deviceInfo.mac &&
this.formData.code.trim() &&
this.formData.regionId
);
},
},
methods: {
// 扫码获取SN
async handleScanCode() {
try {
uni.showLoading({ title: "扫码中...", mask: true });
// 调用扫码功能
const res = await new Promise((resolve, reject) => {
uni.scanCode({
onlyFromCamera: true,
scanType: ["qrCode"],
success: (result) => {
resolve(result);
},
fail: (error) => {
reject(error);
},
});
});
uni.hideLoading();
if (res.result) {
// 解析二维码内容提取SN参数
let sn = null;
let queryParams = res.result.split("?")[1];
if (queryParams) {
let params = queryParams.split("&");
params.forEach((param) => {
let [key, value] = param.split("=");
if (key === "s") {
sn = value;
}
});
}
// 如果没有从URL参数中获取到SN尝试直接使用结果
if (!sn) {
sn = res.result.trim();
}
console.log("扫码获取到SN:", sn);
console.log("原始扫码结果:", res.result);
if (sn) {
// 通过SN获取设备信息
await this.getDeviceInfoBySn(sn);
} else {
uni.showToast({
title: "未找到有效的SN码",
icon: "none",
});
}
}
} catch (error) {
uni.hideLoading();
console.error("扫码失败:", error);
if (error.errMsg && error.errMsg.includes("cancel")) {
// 用户取消扫码,不显示错误提示
return;
}
uni.showToast({
title: "扫码失败,请重试",
icon: "none",
});
}
},
// 通过SN获取设备信息
async getDeviceInfoBySn(sn) {
try {
uni.showLoading({ title: "获取设备信息...", mask: true });
// 调用API获取设备信息
const res = await this.$request.get("/bst/memorial/getBySn", {
sn: sn,
});
uni.hideLoading();
console.log("@@@@@@@@@@@@@@@@@@@@", res);
if (res) {
const deviceData = res;
this.deviceInfo = {
sn: deviceData.sn || sn,
mac: deviceData.mac || "",
name: deviceData.name || "",
id: deviceData.id || "",
};
uni.showToast({
title: "设备信息获取成功",
icon: "success",
});
console.log("设备信息:", this.deviceInfo);
} else {
throw new Error(res?.msg || "获取设备信息失败");
}
} catch (error) {
uni.hideLoading();
console.error("获取设备信息失败:", error);
uni.showToast({
title: error.message || "获取设备信息失败",
icon: "none",
});
}
},
// 区域选择
onRegionChange(e) {
this.regionIndex = e.detail.value;
this.formData.regionId = this.regionOptions[this.regionIndex];
},
// 取消操作
handleCancel() {
uni.navigateBack();
},
// 确认添加
async handleConfirm() {
if (!this.canSubmit) {
uni.showToast({
title: "请完善必填信息",
icon: "none",
});
return;
}
// 表单验证
if (!this.validateForm()) {
return;
}
try {
uni.showLoading({ title: "添加中...", mask: true });
// 构建请求数据
const requestData = {
id: this.deviceInfo.id, // 使用设备ID
code: this.formData.code,
name: this.formData.name,
regionId: this.getRegionId(this.formData.regionId),
orderNum: this.formData.orderNum || "1",
sn: this.deviceInfo.sn,
mac: this.deviceInfo.mac,
remark: this.formData.remark,
};
console.log("提交数据:", requestData);
// 调用API添加牌位
const res = await this.$request.put("/bst/memorial", requestData);
uni.hideLoading();
if (res && (res.code === 200 || res.status === 200)) {
uni.showToast({
title: "添加成功",
icon: "success",
});
// 延迟返回上一页
setTimeout(() => {
uni.navigateBack();
}, 1500);
} else {
throw new Error(res?.msg || "添加失败");
}
} catch (error) {
uni.hideLoading();
console.error("添加牌位失败:", error);
uni.showToast({
title: error.message || "添加失败,请重试",
icon: "none",
});
}
},
// 表单验证
validateForm() {
if (!this.formData.code.trim()) {
uni.showToast({
title: "请输入牌位编号",
icon: "none",
});
return false;
}
if (!this.formData.regionId) {
uni.showToast({
title: "请选择所属区域",
icon: "none",
});
return false;
}
return true;
},
// 获取区域ID根据实际业务逻辑调整
getRegionId(regionName) {
const regionMap = {
A区: "1",
B区: "2",
C区: "3",
D区: "4",
};
return regionMap[regionName] || "1";
},
},
};
</script>
<style lang="scss" scoped>
.page {
width: 100%;
min-height: 100vh;
background: #f5f5f5;
}
.content {
padding: 20rpx;
padding-bottom: 120rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
padding-left: 10rpx;
border-left: 6rpx solid #4a90e2;
}
.scan-section {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.scan-container {
margin-bottom: 30rpx;
}
.scan-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 200rpx;
border: 3rpx dashed #4a90e2;
border-radius: 16rpx;
background: #f8fbff;
transition: all 0.3s ease;
&:active {
background: #e8f4ff;
transform: scale(0.98);
}
}
.qrcode-icon {
width: 60rpx;
height: 60rpx;
margin-bottom: 10rpx;
image {
width: 100%;
height: 100%;
}
}
.scan-text {
font-size: 28rpx;
color: #4a90e2;
font-weight: 500;
}
.device-info {
background: #f8f9fa;
border-radius: 12rpx;
padding: 20rpx;
border: 2rpx solid #e9ecef;
}
.info-item {
display: flex;
align-items: center;
margin-bottom: 15rpx;
&:last-child {
margin-bottom: 0;
}
}
.info-label {
font-size: 26rpx;
color: #666;
width: 140rpx;
flex-shrink: 0;
}
.info-value {
font-size: 26rpx;
color: #333;
font-weight: 500;
flex: 1;
word-break: break-all;
}
.form-section {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.form-container {
// 表单容器样式
}
.form-item {
margin-bottom: 30rpx;
&:last-child {
margin-bottom: 0;
}
}
.label {
font-size: 28rpx;
color: #666;
margin-bottom: 12rpx;
font-weight: 500;
}
.required {
color: #ff4757;
margin-left: 4rpx;
}
.input {
width: 100%;
height: 80rpx;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
color: #333;
box-sizing: border-box;
background: #fff;
&:focus {
border-color: #4a90e2;
}
}
.picker {
width: 100%;
height: 80rpx;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
display: flex;
align-items: center;
padding: 0 20rpx;
background: #fff;
box-sizing: border-box;
}
.picker-text {
font-size: 28rpx;
color: #333;
flex: 1;
}
.textarea {
width: 100%;
min-height: 120rpx;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
padding: 20rpx;
font-size: 28rpx;
color: #333;
box-sizing: border-box;
background: #fff;
resize: none;
&:focus {
border-color: #4a90e2;
}
}
.button-container {
display: flex;
gap: 20rpx;
padding: 0 20rpx;
}
.btn {
flex: 1;
height: 88rpx;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: bold;
transition: all 0.3s ease;
}
.cancel-btn {
background: #f5f5f5;
color: #666;
border: 2rpx solid #e5e5e5;
&:active {
background: #e8e8e8;
}
}
.confirm-btn {
background: #4a90e2;
color: #fff;
box-shadow: 0 4rpx 12rpx rgba(74, 144, 226, 0.3);
&:active {
background: #357abd;
}
&.disabled {
background: #ccc;
color: #999;
box-shadow: none;
&:active {
background: #ccc;
}
}
}
</style>