| | |
| | | <template> |
| | | <Splash v-if="showSplash" /> |
| | | <div v-else> |
| | | <router-view /> |
| | | </div> |
| | | <Splash v-if="showSplash" /> |
| | | <div v-else> |
| | | <router-view /> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import { ref, onMounted } from 'vue' |
| | | import Splash from './components/Splash.vue' |
| | | import { ref, onMounted } from "vue"; |
| | | import Splash from "./components/Splash.vue"; |
| | | |
| | | const showSplash = ref(true) |
| | | onMounted(() => { |
| | | setTimeout(() => { |
| | | showSplash.value = false |
| | | }, 5000) |
| | | }) |
| | | const showSplash = ref(true); |
| | | onMounted(() => { |
| | | setTimeout(() => { |
| | | showSplash.value = false; |
| | | }, 5000); |
| | | |
| | | // 初始化推送服务 |
| | | initPushService(); |
| | | }); |
| | | // 初始化推送服务(uni-push 1.0) |
| | | const initPushService = () => { |
| | | // #ifdef APP-PLUS |
| | | console.log("开始初始化推送服务(uni-push 1.0)"); |
| | | if (typeof plus !== "undefined" && plus.push) { |
| | | console.log("plus.push 存在:", plus.push); |
| | | |
| | | // 获取客户端推送标识 |
| | | console.log("使用 plus.push.getClientInfo 获取客户端标识"); |
| | | plus.push.getClientInfoAsync(info => { |
| | | console.log("客户端推送标识:", info); |
| | | // 这里可以将客户端标识发送到服务器 |
| | | }); |
| | | setTimeout(() => { |
| | | console.log("使用 plus.push.getClientInfoAsync 获取客户端标识"); |
| | | plus.push.getClientInfoAsync(info => { |
| | | console.log("客户端推送标识:", info); |
| | | // 这里可以将客户端标识发送到服务器 |
| | | }); |
| | | }, 1000); |
| | | |
| | | // 监听推送消息点击事件 |
| | | plus.push.addEventListener("click", handlePushClick, false); |
| | | // 监听推送消息接收事件 |
| | | plus.push.addEventListener("receive", handlePushReceive, false); |
| | | console.log("推送服务注册成功"); |
| | | } else { |
| | | console.log("推送服务不可用"); |
| | | } |
| | | // #endif |
| | | }; |
| | | |
| | | // 处理推送消息点击事件 |
| | | const handlePushClick = msg => { |
| | | console.log("点击推送消息:", msg); |
| | | uni.navigateTo({ |
| | | url: msg.payload.pagePath, |
| | | }); |
| | | // 解析并处理推送消息... |
| | | }; |
| | | |
| | | // 处理推送消息接收事件 |
| | | const handlePushReceive = msg => { |
| | | console.log("收到推送消息:", msg); |
| | | // 处理接收的推送消息... |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | @import "uview-plus/index.scss"; |
| | | @import '@/static/scss/index.scss'; |
| | | @import "uview-plus/index.scss"; |
| | | @import "@/static/scss/index.scss"; |
| | | </style> |
| | |
| | | /* 模块配置 */ |
| | | "modules" : { |
| | | "Camera" : {}, |
| | | "Barcode" : {} |
| | | "Barcode" : {}, |
| | | "Push" : {}, |
| | | "Maps" : {} |
| | | }, |
| | | /* 应用发布信息 */ |
| | | "distribute" : { |
| | |
| | | "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", |
| | | "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", |
| | | "<uses-feature android:name=\"android.hardware.camera\"/>", |
| | | "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" |
| | | "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>", |
| | | "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>", |
| | | "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>", |
| | | "<uses-permission android:name=\"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\"/>", |
| | | "<uses-feature android:name=\"android.hardware.location\"/>", |
| | | "<uses-feature android:name=\"android.hardware.location.gps\"/>", |
| | | "<uses-feature android:name=\"android.hardware.location.network\"/>" |
| | | ] |
| | | }, |
| | | /* ios打包配置 */ |
| | | "ios" : { |
| | | "dSYMs" : false |
| | | "dSYMs" : false, |
| | | "plist" : { |
| | | "NSLocationWhenInUseUsageDescription" : "需要获取您的位置信息来记录客户拜访地点", |
| | | "NSLocationAlwaysAndWhenInUseUsageDescription" : "需要获取您的位置信息来记录客户拜访地点" |
| | | } |
| | | }, |
| | | /* SDK配置 */ |
| | | "sdkConfigs" : { |
| | |
| | | "small" : { |
| | | "ldpi" : "D:/xindao/wenjian/img/logo/app.png" |
| | | } |
| | | } |
| | | }, |
| | | "offline" : false |
| | | } |
| | | }, |
| | | "maps" : { |
| | | "amap" : { |
| | | "name" : "amap_18330707920ae9zOwCD", |
| | | "appkey_ios" : "c2b4e3889ab4cb9468e9c8ae4f3ab53f", |
| | | "appkey_android" : "c2b4e3889ab4cb9468e9c8ae4f3ab53f" |
| | | } |
| | | } |
| | | }, |
| | |
| | | }, |
| | | fail: err => { |
| | | uni.hideLoading(); |
| | | showToast("获取位置失败,请检查定位权限"); |
| | | console.error("获取位置失败:", err); |
| | | |
| | | // 显示错误提示并引导用户检查权限 |
| | | showToast("获取位置失败,请检查定位权限"); |
| | | |
| | | // 引导用户检查权限设置 |
| | | uni.showModal({ |
| | | title: "位置权限提示", |
| | | content: |
| | | "获取位置失败,可能是因为位置权限未开启,请在设备设置中检查并开启位置权限。", |
| | | confirmText: "知道了", |
| | | cancelText: "取消", |
| | | success: res => { |
| | | if (res.confirm) { |
| | | // 可以尝试打开设置页面(如果支持) |
| | | if (uni.openSetting) { |
| | | uni.openSetting({ |
| | | success: settingRes => { |
| | | console.log("设置结果:", settingRes); |
| | | }, |
| | | }); |
| | | } |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | // 失败时显示错误信息 |
| | | form.value.visitAddress = "位置获取失败"; |
| | | }, |
| | |
| | | return |
| | | } |
| | | |
| | | const submitData = { |
| | | const submitData = [{ |
| | | ...form.value, |
| | | productData: productData.value |
| | | } |
| | | }] |
| | | |
| | | await addOrUpdateRegistration(submitData) |
| | | showToast('提交成功') |
| | |
| | | <text class="detail-label">供应商名称</text> |
| | | <text class="detail-value">{{ item.supplierName }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <!-- <view class="detail-row"> |
| | | <text class="detail-label">发票号</text> |
| | | <text class="detail-value">{{ item.invoiceNumber }}</text> |
| | | </view> |
| | | </view> --> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">产品大类</text> |
| | | <text class="detail-value">{{ item.productCategory }}</text> |
| | |
| | | v-if="!isReadOnly" |
| | | @click="removeApprover(stepIndex)">×</view> |
| | | </view> |
| | | <view v-else |
| | | <view v-else-if="!isReadOnly" |
| | | class="add-approver-btn" |
| | | v-if="!isReadOnly" |
| | | @click="addApprover(stepIndex)"> |
| | | <view class="add-circle">+</view> |
| | | <text class="add-label">选择审批人</text> |
| | |
| | | const form = ref({ |
| | | id: "", |
| | | salesContractNo: "", |
| | | // 关联销售台账ID(编辑回显时可能缺失,需要从合同号反查补齐) |
| | | salesLedgerId: "", |
| | | purchaseContractNumber: "", |
| | | supplierId: "", |
| | | supplierName: "", |
| | |
| | | form.value.salesLedgerId = selectedItem.value; |
| | | } |
| | | showPicker.value = false; |
| | | }; |
| | | |
| | | // 编辑回显场景:只有 salesContractNo,没有 salesLedgerId 时,尝试从列表反查补齐 |
| | | const syncSalesLedgerIdFromContractNo = () => { |
| | | if (form.value.salesLedgerId) return; |
| | | if (!form.value.salesContractNo) return; |
| | | const selectedItem = salesContractList.value.find( |
| | | contract => contract.text === form.value.salesContractNo |
| | | ); |
| | | if (selectedItem) { |
| | | form.value.salesLedgerId = selectedItem.value; |
| | | } |
| | | }; |
| | | |
| | | // 供应商选择事件 |
| | |
| | | }); |
| | | return; |
| | | } |
| | | // 如果salesLedgerId为空,则不传递salesContractNo |
| | | if (!form.value.salesLedgerId) { |
| | | form.value.salesContractNo = ""; |
| | | } |
| | | // 编辑回显时可能只有合同号,提交前尝试补齐 salesLedgerId |
| | | syncSalesLedgerIdFromContractNo(); |
| | | if (operationType.value == "add") { |
| | | delete form.value.id; |
| | | } |
| | |
| | | text: user.salesContractNo, |
| | | value: user.id, |
| | | })); |
| | | // 列表回来后,补齐编辑回显的 salesLedgerId |
| | | syncSalesLedgerIdFromContractNo(); |
| | | }); |
| | | }; |
| | | |
| | |
| | | </view> |
| | | <up-divider></up-divider> |
| | | <view class="item-details"> |
| | | <view class="detail-row"> |
| | | <!-- <view class="detail-row"> |
| | | <text class="detail-label">销售合同号</text> |
| | | <text class="detail-value">{{ item.salesContractNo }}</text> |
| | | </view> |
| | | </view> --> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">供应商名称</text> |
| | | <text class="detail-value">{{ item.supplierName }}</text> |
| | |
| | | <view class="unit">元</view> |
| | | </template> |
| | | </u-form-item> |
| | | <u-form-item label="人员损失情况" |
| | | prop="personLoss" |
| | | border-bottom> |
| | | <u-input v-model="form.personLoss" |
| | | placeholder="请输入人员损失情况" /> |
| | | </u-form-item> |
| | | <u-form-item label="事故直接原因" |
| | | prop="accidentCause" |
| | | border-bottom> |
| | |
| | | accidentGrade: "", |
| | | happenTime: "", |
| | | happenLocation: "", |
| | | personLoss: "", |
| | | createUserName: "", |
| | | createTime: "", |
| | | assetLoss: "", |
| | |
| | | <view class="info-value">{{ accidentInfo.assetLoss || '-' }}<span v-if="accidentInfo.assetLoss">元</span></view> |
| | | </view> |
| | | <view class="info-row"> |
| | | <view class="info-label">人员损失情况:</view> |
| | | <view class="info-value">{{ accidentInfo.personLoss || '-' }}</view> |
| | | </view> |
| | | <view class="info-row"> |
| | | <view class="info-label">上报时间:</view> |
| | | <view class="info-value">{{ accidentInfo.createTime || '-' }}</view> |
| | | </view> |
| | |
| | | // 提交表单 |
| | | const submitForm = async () => { |
| | | // 验证表单必填项 |
| | | if (!formRef.value) return; |
| | | if (!form.value.planCode) { |
| | | showToast("请输入应急预案编码"); |
| | | return; |
| | | } |
| | | |
| | | const valid = await formRef.value.validate(); |
| | | if (!valid) { |
| | | if (!form.value.planName) { |
| | | showToast("请输入应急预案名称"); |
| | | return; |
| | | } |
| | | |
| | | if (!form.value.publishTime) { |
| | | showToast("请选择发布生效时间"); |
| | | return; |
| | | } |
| | | |
| | | if (!form.value.planType) { |
| | | showToast("请选择预案类型"); |
| | | return; |
| | | } |
| | | |
| | | if (!form.value.coreResponsorUserId) { |
| | | showToast("请选择核心责任人"); |
| | | return; |
| | | } |
| | | |
| | | if (!form.value.applyScope || form.value.applyScope.length === 0) { |
| | | showToast("请选择适用范围"); |
| | | return; |
| | | } |
| | | |
| | |
| | | onLoad(() => { |
| | | // 编辑规程资质时,从本地存储获取数据 |
| | | const qualification = uni.getStorageSync("safeQualifications"); |
| | | if (qualification) { |
| | | if (qualification.id) { |
| | | form.value = qualification; |
| | | isEdit.value = true; |
| | | |
| | |
| | | import { delCustomer } from "@/api/cooperativeOffice/clientVisit"; |
| | | import { |
| | | qualificationsListPage, |
| | | safeCertificationAdd, |
| | | safeCertificationUpdate, |
| | | safeCertificationDel, |
| | | fileListPage, |
| | | safeCertificationFileAdd, |
| | | safeCertificationFileDel, |
| | | } from "@/api/safeProduction/safeQualifications"; |
| | | |
| | | import useUserStore from "@/store/modules/user"; |
| | |
| | | <u-form-item label="发票金额(元)" prop="invoiceTotal" required border-bottom> |
| | | <u-input v-model="form.invoiceTotal" type="number" placeholder="请输入" /> |
| | | </u-form-item> |
| | | <view class="tip-text" v-if="Number(maxInvoiceAmount) > 0"> |
| | | 可开票最大金额:{{ formatAmount(maxInvoiceAmount) }} 元 |
| | | </view> |
| | | <u-form-item label="开票人" border-bottom> |
| | | <u-input v-model="form.invoicePerson" readonly /> |
| | | </u-form-item> |
| | |
| | | }) |
| | | const fileList = ref([]) |
| | | const currentId = ref('') |
| | | const maxInvoiceAmount = ref(0) |
| | | |
| | | // 日期选择 |
| | | const showInvoiceDatePicker = ref(false) |
| | |
| | | const res = await invoiceLedgerProductInfo({ id }) |
| | | const data = res?.data || res |
| | | form.value = { ...data } |
| | | // 计算发票金额最大值:noInvoiceAmount + invoiceAmount |
| | | const noInvoiceAmount = parseFloat(data?.noInvoiceAmount || 0) |
| | | const invoiceAmount = parseFloat(data?.invoiceAmount || 0) |
| | | maxInvoiceAmount.value = (Number.isNaN(noInvoiceAmount) ? 0 : noInvoiceAmount) + (Number.isNaN(invoiceAmount) ? 0 : invoiceAmount) |
| | | fileList.value = data?.fileList || [] |
| | | if (!form.value.invoicePerson) { |
| | | form.value.invoicePerson = userStore.nickName |
| | |
| | | if (!form.value.invoiceNo) { showToast('请输入发票号'); return } |
| | | if (!form.value.invoiceTotal) { showToast('请输入发票金额'); return } |
| | | if (!form.value.invoiceDate) { showToast('请选择开票日期'); return } |
| | | |
| | | // 校验:发票金额不能超过最大值 |
| | | const invoiceTotal = parseFloat(form.value.invoiceTotal || 0) |
| | | if (Number.isNaN(invoiceTotal) || invoiceTotal <= 0) { |
| | | showToast('请输入有效的发票金额') |
| | | return |
| | | } |
| | | if (maxInvoiceAmount.value > 0 && invoiceTotal - maxInvoiceAmount.value > 1e-6) { |
| | | showToast(`发票金额不能超过最大值:${formatAmount(maxInvoiceAmount.value)}`) |
| | | return |
| | | } |
| | | showLoadingToast('提交中...') |
| | | form.value.fileList = fileList.value |
| | | await invoiceLedgerSaveOrUpdate(form.value) |
| | |
| | | .uploaded-list { padding: 8px 16px 0 16px; } |
| | | .uploaded-item { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f5f5f5; } |
| | | .file-name { font-size: 12px; color: #333; margin-right: 8px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| | | .tip-text { padding: 4px 16px 0 16px; font-size: 12px; color: #888; } |
| | | .tip-text { padding: 4px 0; font-size: 12px; color: #888; } |
| | | .footer-btns { |
| | | position: fixed; |
| | | left: 0; |