Merge branch 'master' of http://139.196.74.78:10010/r/jagzwxm/ja_web
36 files modified
1 files deleted
1 files added
| | |
| | | //变量 |
| | | $gd-placeholder: #86909C; |
| | | $form-bg: #F2F3F5; |
| | | |
| | | .gd-table { |
| | | height: 0; |
| | | flex: 1; |
| | | background: transparent !important; |
| | | |
| | | .el-table--border .el-table__inner-wrapper:after, |
| | | .el-table--border:after, |
| | | .el-table--border:before, |
| | | .el-table__inner-wrapper:before { |
| | | height: 0; |
| | | } |
| | | |
| | | tr { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | th.el-table__cell { |
| | | height: 40px; |
| | | border-bottom: 1px solid #DBDFF1 !important; |
| | | |
| | | .cell { |
| | | padding: 0 0 0 16px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #9292C1; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | |
| | | td.el-table__cell { |
| | | padding: 9px 0; |
| | | height: 56px; |
| | | |
| | | .cell { |
| | | padding: 0 0 0 16px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #383874; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | |
| | | td.operation-btns .cell { |
| | | display: flex; |
| | | flex-wrap: nowrap; |
| | | gap: 12px; |
| | | /* 按钮间距(推荐) */ |
| | | white-space: nowrap; |
| | | /* 双保险 */ |
| | | |
| | | a { |
| | | min-width: 28px; |
| | | color: #0075FF; |
| | | |
| | | &:last-child { |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | th.el-table__cell:not(.fixed-column), |
| | | td.el-table__cell:not(.fixed-column) { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | .fixed-column { |
| | | background-color: #1A1A2A !important; |
| | | } |
| | | } |
| | | $form-tips: #86909C; |
| | | //灰色变量 |
| | | $form-bg-gray: #DDE2ED; |
| | | $form-tips-gray: #A1A3D4; |
| | | |
| | | .gd-input { |
| | | --el-input-bg-color: #{$form-bg}; |
| | | --el-input-placeholder-color: #{$form-tips}; |
| | | |
| | | &.gray { |
| | | --el-input-bg-color: #{$form-bg-gray}; |
| | | --el-input-placeholder-color: #{$form-tips-gray}; |
| | | } |
| | | |
| | | .el-input__wrapper, .el-textarea__inner { |
| | | padding: 0 8px !important; |
| | | background: $form-bg; |
| | | box-shadow: none !important; |
| | | border: none; |
| | | } |
| | | |
| | | .el-input__inner, .el-textarea__inner { |
| | | &::placeholder { |
| | | color: $gd-placeholder; |
| | | } |
| | | } |
| | | |
| | | |
| | | &.is-disabled { |
| | | .el-input__wrapper { |
| | | background: #DDE2ED; |
| | | background: $form-bg; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .gd-select { |
| | | .el-select__input { |
| | | color: #8ac3fd !important; |
| | | .gd-select, { |
| | | --bg: #{$form-bg}; |
| | | --tips: #{$form-tips}; |
| | | |
| | | &.gray { |
| | | --bg: #{$form-bg-gray}; |
| | | --tips: #{$form-tips-gray}; |
| | | } |
| | | |
| | | .el-select__wrapper { |
| | | padding: 0 8px; |
| | | background: $form-bg; |
| | | background: var(--bg); |
| | | box-shadow: none !important; |
| | | border: none; |
| | | width: 100%; |
| | | } |
| | | |
| | | .el-select__placeholder { |
| | | &.is-transparent { |
| | | color: $gd-placeholder !important; |
| | | color: var(--tips) !important; |
| | | } |
| | | |
| | | &.el-select__selected-item { |
| | | color: #383874; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-select { |
| | | --el-select-border-color-hover: rgb(0, 162, 255) !important; |
| | | .gd-date-picker { |
| | | --bg: #{$form-bg}; |
| | | --tips: #{$form-tips}; |
| | | |
| | | &.gray { |
| | | --bg: #{$form-bg-gray}; |
| | | --tips: #{$form-tips-gray}; |
| | | } |
| | | |
| | | .el-input { |
| | | --el-border-color: rgb(0, 162, 255); |
| | | } |
| | | |
| | | .el-select .el-input__wrapper { |
| | | background-color: #DDE2ED !important; |
| | | } |
| | | box-shadow: none !important; |
| | | background: var(--bg); |
| | | border: none; |
| | | border-radius: 5px; |
| | | box-sizing: border-box !important; |
| | | |
| | | .el-input__wrapper { |
| | | --el-input-text-color: #DDE2ED !important; |
| | | box-shadow: none !important; |
| | | background-color: transparent !important; |
| | | |
| | | &.is-focus { |
| | | box-shadow: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-range-input { |
| | | &::placeholder { |
| | | color: var(--tips); |
| | | } |
| | | } |
| | | |
| | | .el-range-separator { |
| | | color: #ffffff; |
| | | } |
| | | } |
| | | |
| | |
| | | background: #012a50 !important; |
| | | border: 1px solid #012a50 !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .gd-date-picker { |
| | | box-shadow: none !important; |
| | | background: $form-bg; |
| | | border: none; |
| | | border-radius: 5px; |
| | | box-sizing: border-box !important; |
| | | |
| | | .el-input__wrapper { |
| | | box-shadow: none !important; |
| | | background-color: transparent !important; |
| | | |
| | | &.is-focus { |
| | | box-shadow: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-range-input { |
| | | color: #fff; |
| | | |
| | | &::placeholder { |
| | | color: $gd-placeholder; |
| | | } |
| | | } |
| | | |
| | | .el-range-separator { |
| | | color: #ffffff; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | .el-overlay-dialog{ |
| | | .el-overlay-dialog { |
| | | display: flex; |
| | | justify-content: center; /* 水平居中 */ |
| | | align-items: center; /* 垂直居中 */ |
| | | align-items: center; /* 垂直居中 */ |
| | | } |
| | | |
| | | .gd-dialog { |
| | |
| | | |
| | | .el-dialog__body { |
| | | overflow: auto; |
| | | min-height: 20vh; |
| | | min-height: 5vh; |
| | | |
| | | .detail-title { |
| | | margin-bottom: 10px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | |
| | | margin-bottom: 0; |
| | | |
| | | .label { |
| | | display: inline-block; |
| | | width: 88px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 500; |
| | |
| | | .save-btn { |
| | | color: #FFFFFF; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .gd-table { |
| | | height: 0; |
| | | flex: 1; |
| | | background: transparent !important; |
| | | |
| | | .el-table--border .el-table__inner-wrapper:after, |
| | | .el-table--border:after, |
| | | .el-table--border:before, |
| | | .el-table__inner-wrapper:before { |
| | | height: 0; |
| | | } |
| | | |
| | | tr { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | th.el-table__cell { |
| | | height: 40px; |
| | | border-bottom: 1px solid #DBDFF1 !important; |
| | | |
| | | .cell { |
| | | padding: 0 0 0 16px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #9292C1; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | |
| | | td.el-table__cell { |
| | | padding: 9px 0; |
| | | height: 56px; |
| | | |
| | | .cell { |
| | | padding: 0 0 0 16px; |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #383874; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | |
| | | td.operation-btns .cell { |
| | | display: flex; |
| | | flex-wrap: nowrap; |
| | | gap: 12px; |
| | | /* 按钮间距(推荐) */ |
| | | white-space: nowrap; |
| | | /* 双保险 */ |
| | | |
| | | a { |
| | | min-width: 28px; |
| | | color: #0075FF; |
| | | |
| | | &:last-child { |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | th.el-table__cell:not(.fixed-column), |
| | | td.el-table__cell:not(.fixed-column) { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | .fixed-column { |
| | | background-color: #1A1A2A !important; |
| | | } |
| | | } |
| | | |
| | |
| | | text-transform: none; |
| | | } |
| | | |
| | | background: #F2F3F5; |
| | | background: $form-bg; |
| | | border: none; |
| | | box-shadow: none; |
| | | } |
| | |
| | | .gd-input { |
| | | width: 200px; |
| | | height: 36px; |
| | | |
| | | .el-input__wrapper { |
| | | } |
| | | |
| | | &.is-disabled { |
| | | .el-input__wrapper { |
| | | } |
| | | } |
| | | } |
| | | |
| | | .gd-date-picker { |
| | | } |
| | | |
| | | .gd-date-picker-popper { |
| | | |
| | | .el-picker-panel { |
| | | .el-picker-panel__body-wrapper { |
| | | .el-picker-panel__body { |
| | | |
| | | .el-date-picker__time-header { |
| | | |
| | | .el-date-picker__editor-wrap { |
| | | .el-time-panel { |
| | | |
| | | // 将 time-picker-popper 的样式移到这里 |
| | | .el-time-panel__header { |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-popper__arrow { |
| | | &::before { |
| | | background: #DDE2ED !important; |
| | | border: 1px solid #DDE2ED !important; |
| | | box-sizing: border-box; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .gd-search-actions { |
| | |
| | | |
| | | .gd-select-popper { |
| | | border: none; |
| | | background: #F2F3F5 !important; |
| | | background: $form-bg !important; |
| | | |
| | | .el-select-dropdown { |
| | | .el-scrollbar { |
| | |
| | | } |
| | | |
| | | .el-select-dropdown__empty { |
| | | background: #F2F3F5; |
| | | background: $form-bg; |
| | | border-radius: 0px 0px 8px 8px; |
| | | } |
| | | } |
| | | |
| | | .el-popper__arrow::before { |
| | | background: #F2F3F5 !important; |
| | | background: $form-bg !important; |
| | | border: 1px solid #F2F3F5 !important; |
| | | } |
| | | } |
| | | |
| | | .gd-timeline { |
| | | padding-left: 120px; |
| | | |
| | | .el-timeline-item { |
| | | height: 120px; |
| | | |
| | | &:nth-last-child(1) { |
| | | height: auto; |
| | | } |
| | | |
| | | .el-timeline-item__tail { |
| | | left: 15px; |
| | | transform: translate(-15px); |
| | | border-left-color: #4c34ff; |
| | | } |
| | | |
| | | .el-timeline-item__node { |
| | | width: 32px; |
| | | height: 32px; |
| | | background-color: #161b2c; |
| | | transform: translate(-15px); |
| | | |
| | | &.el-timeline-item__node--success { |
| | | background-color: #4c34ff; |
| | | } |
| | | |
| | | .el-timeline-item__icon { |
| | | font-size: 22px; |
| | | } |
| | | } |
| | | |
| | | .el-timeline-item__wrapper { |
| | | top: 5px; |
| | | font-size: 16px; |
| | | |
| | | .el-timeline-item__timestamp { |
| | | margin-top: 20px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | :model="formData" |
| | | :rules="rules" |
| | | :disabled="dialogReadonly" |
| | | label-width="100px" |
| | | label-width="140px" |
| | | > |
| | | <el-row> |
| | | <el-col :span="12"> |
| | |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | v-if="!dialogReadonly" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | @click="handleSubmit" |
| | | > |
| | | 保存 |
| | | </el-button> |
| | | <template v-if="!dialogReadonly"> |
| | | <el-button color="#F2F3F5" @click="visible = false">取消</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | @click="handleSubmit" |
| | | > |
| | | 提交 |
| | | </el-button> |
| | | </template> |
| | | <template v-if="dialogReadonly && innovationDetailsStatus ==='0'"> |
| | | <el-button color="#F2F3F5" @click="handleReject">不通过</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | @click="handleApprove" |
| | | > |
| | | 通过 |
| | | </el-button> |
| | | </template> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | |
| | | caseDesc: '', |
| | | innovationStatus: '', |
| | | }) |
| | | |
| | | const innovationDetailsStatus = inject('innovationDetailsStatus') |
| | | const emit = defineEmits(['success']) |
| | | const formRef = ref(null) // 表单实例 |
| | | const formData = ref(initForm()) // 表单数据 |
| | |
| | | if (!isValid) return |
| | | submitting.value = true |
| | | try { |
| | | formData.value.innovationStatus = dialogMode.value === 'add' ? '0' : formData.value.innovationStatus |
| | | await gdApplicationInnovationSubmitApi(formData.value) |
| | | ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功') |
| | | visible.value = false |
| | | emit('success') |
| | | } finally { |
| | | submitting.value = false |
| | | } |
| | | } |
| | | |
| | | // 处理通过 |
| | | async function handleApprove() { |
| | | submitting.value = true |
| | | try { |
| | | formData.value.innovationStatus = '1' |
| | | await gdApplicationInnovationSubmitApi(formData.value) |
| | | ElMessage.success('审批通过成功') |
| | | visible.value = false |
| | | emit('success') |
| | | } finally { |
| | | submitting.value = false |
| | | } |
| | | } |
| | | |
| | | // 处理不通过 |
| | | async function handleReject() { |
| | | submitting.value = true |
| | | try { |
| | | formData.value.innovationStatus = '2' |
| | | await gdApplicationInnovationSubmitApi(formData.value) |
| | | ElMessage.success('审批不通过成功') |
| | | visible.value = false |
| | | emit('success') |
| | | } finally { |
| | |
| | | |
| | | defineExpose({ open }) |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | |
| | | </style> |
| | |
| | | <basic-container> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="案例名称" prop="caseName"> |
| | | <el-input class="gd-input" v-model="searchParams.caseName" placeholder="请输入" clearable @clear="handleSearch" /> |
| | | <el-input |
| | | class="gd-input gray" |
| | | v-model="searchParams.caseName" |
| | | placeholder="请输入" |
| | | clearable |
| | | @clear="handleSearch" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="应用创新状态" prop="innovationStatus"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.innovationStatus" |
| | | placeholder="请选择" |
| | | clearable |
| | | @change="handleSearch" |
| | | > |
| | | <el-option v-for="item in dictObj.appInnovationStatus" :key="item.dictKey" |
| | | <el-option |
| | | v-for="item in dictObj.appInnovationStatus" |
| | | :key="item.dictKey" |
| | | :label="item.dictValue" |
| | | :value="item.dictKey"/> |
| | | :value="item.dictKey" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | |
| | | <el-table-column prop="belongDomain" show-overflow-tooltip label="所属领域" /> |
| | | <el-table-column prop="innovationStatus" show-overflow-tooltip label="应用创新状态"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDictLabel(row.innovationStatus) }} |
| | | {{ getDictLabel(row.innovationStatus, dictObj.appInnovationStatus) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="applicationScenarioDesc" show-overflow-tooltip label="应用场景描述" /> |
| | |
| | | <el-table-column prop="resourceName" show-overflow-tooltip label="资源名称" /> |
| | | <el-table-column prop="resourceCode" show-overflow-tooltip label="资源编码" /> |
| | | <el-table-column prop="caseDesc" show-overflow-tooltip label="案例描述" /> |
| | | <el-table-column label="操作" class-name="operation-btns"> |
| | | <el-table-column label="操作" class-name="operation-btns" width="180"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <!-- <el-link @click="openForm('edit', row)">编辑</el-link>--> |
| | | <el-link @click="handleDelete(row)">删除</el-link> |
| | | <el-link @click="handleDelete(row)" v-if="!['1', '2'].includes(row.innovationStatus)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | const dialogRef = ref(null) // 弹框实例 |
| | | const dialogVisible = ref(false) |
| | | const dictObj = ref({}) // 字典对象 |
| | | const innovationDetailsStatus = ref( '') |
| | | provide('dictObj', dictObj) |
| | | provide('innovationDetailsStatus', innovationDetailsStatus) |
| | | // 获取字典 |
| | | function getDictList() { |
| | | return getDictionaryByCode('appInnovationStatus').then(res => { |
| | | dictObj.value = res.data.data |
| | | |
| | | }) |
| | | } |
| | | |
| | | |
| | | // 获取列表 |
| | | async function getList() { |
| | |
| | | |
| | | // 新增/编辑/查看 弹框 |
| | | function openForm(mode, row) { |
| | | innovationDetailsStatus.value = row?.innovationStatus |
| | | dialogVisible.value = true |
| | | nextTick(() => { |
| | | dialogRef.value?.open({ mode, row }) |
| | |
| | | }) |
| | | </script> |
| | | <style scoped lang="scss"></style> |
| | | |
| | |
| | | <template #footer> |
| | | <template v-if="!dialogReadonly"> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | color="#F2F3F5" |
| | | |
| | | v-if="!dialogReadonly" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | |
| | | > |
| | | 保存 |
| | | </el-button> |
| | | <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | <el-button class="save-btn" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | </template> |
| | | <template v-if="dialogReadonly && detailObjectionStatus === '1'"> |
| | | <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="visible = false">取消</el-button> |
| | |
| | | </el-button> |
| | | </template> |
| | | <template v-if="detailObjectionStatus === '2'"> |
| | | <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="visible = false">关闭</el-button> |
| | | <!-- <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="visible = false">关闭</el-button>--> |
| | | </template> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | <basic-container> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="异议标题" prop="title"> |
| | | <el-input class="gd-input" v-model="searchParams.title" placeholder="请输入" clearable @clear="handleSearch" /> |
| | | <el-input |
| | | class="gd-input gray" |
| | | v-model="searchParams.title" |
| | | placeholder="请输入" |
| | | clearable |
| | | @clear="handleSearch" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="异议状态" prop="objectionStatus"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.objectionStatus" |
| | | placeholder="请选择" |
| | |
| | | |
| | | <div class="gd-table-toolbar"> |
| | | <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">数据异议申请</el-button> |
| | | <!-- --> |
| | | <!-- --> |
| | | </div> |
| | | |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list"> |
| | | <el-table-column label="序号" width="60"> |
| | | <template v-slot="{ $index }"> |
| | | {{ String($index + 1).padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="序号" width="60"> |
| | | <template v-slot="{ $index }"> |
| | | {{ String($index + 1).padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="title" show-overflow-tooltip label="标题" /> |
| | | <el-table-column prop="objectionType" show-overflow-tooltip label="异议类别"> |
| | | <template v-slot="{ row }"> |
| | |
| | | {{ getDictLabel(row.objectionStatus, dictObj.objectionStatus) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="catalogResourceName" show-overflow-tooltip label="目录/申请资源名称" /> |
| | | <el-table-column prop="catalogResourceName" width="170" show-overflow-tooltip label="目录/申请资源名称" /> |
| | | <el-table-column prop="otherObjectionDetail" show-overflow-tooltip label="其他异议详情" /> |
| | | <el-table-column prop="submitter" show-overflow-tooltip label="问题提交人" /> |
| | | <el-table-column prop="submitterContact" show-overflow-tooltip label="提交人联系方式" /> |
| | | <el-table-column prop="submitterContact" show-overflow-tooltip width="145" label="提交人联系方式" /> |
| | | <el-table-column prop="submitUnitName" show-overflow-tooltip label="提交单位" /> |
| | | <el-table-column prop="handleUnit" show-overflow-tooltip label="处理单位" /> |
| | | <el-table-column prop="objectionDesc" show-overflow-tooltip label="异议描述" /> |
| | | <el-table-column prop="objectionBasis" show-overflow-tooltip label="异议依据" /> |
| | | <el-table-column prop="attachName" show-overflow-tooltip label="附件名称" /> |
| | | <el-table-column prop="reviewOpinion" show-overflow-tooltip label="审核意见" /> |
| | | <el-table-column label="操作" class-name="operation-btns" width="140"> |
| | | <el-table-column label="操作" class-name="operation-btns" width="180"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <el-link @click="openForm('edit', row)" v-if="!['1', '2'].includes(row.objectionStatus)">编辑</el-link> |
| | |
| | | ElMessage.success('删除成功') |
| | | getList() |
| | | } |
| | | |
| | | |
| | | |
| | | // 获取部门树 |
| | | function getDeptTreeFun() { |
| | |
| | | :model="formData" |
| | | :rules="rules" |
| | | :disabled="dialogReadonly" |
| | | label-width="80px" |
| | | label-width="140px" |
| | | > |
| | | <el-row> |
| | | <el-col :span="12"> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <template #footer v-if="!dialogReadonly"> |
| | | <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | v-if="!dialogReadonly" |
| | | |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | @click="handleSubmit" |
| | |
| | | <basic-container> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="标题" prop="title"> |
| | | <el-input class="gd-input" v-model="searchParams.title" placeholder="请输入" clearable @clear="handleSearch" /> |
| | | <el-input |
| | | class="gd-input gray" |
| | | v-model="searchParams.title" |
| | | placeholder="请输入" |
| | | clearable |
| | | @clear="handleSearch" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="是否解决" prop="isResolved"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.isResolved" |
| | | placeholder="请选择" |
| | |
| | | </el-form> |
| | | |
| | | <div class="gd-table-toolbar"> |
| | | <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button> |
| | | <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button> |
| | | <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增评价</el-button> |
| | | </div> |
| | | |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="46" /> |
| | | <el-table class="gd-table" :data="list"> |
| | | <el-table-column label="序号" width="80"> |
| | | <template v-slot="{ $index }"> |
| | | {{ ((searchParams.current - 1) * searchParams.size + $index + 1).toString().padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="title" show-overflow-tooltip label="标题" /> |
| | | <el-table-column prop="dataName" show-overflow-tooltip label="数据名称" /> |
| | | <el-table-column prop="proposeDeptName" show-overflow-tooltip label="提出部门" /> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="evaluationContent" show-overflow-tooltip label="评价内容" /> |
| | | <el-table-column label="操作" class-name="operation-btns"> |
| | | <el-table-column label="操作" class-name="operation-btns" width="180"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <el-link @click="openForm('edit', row)">编辑</el-link> |
| | |
| | | const total = ref(0) // 总条数 |
| | | const loading = ref(true) // 列表加载中 |
| | | const list = ref([]) // 列表数据 |
| | | const selectedIds = ref([]) // 勾选的ID列表 |
| | | const queryParamsRef = ref(null) // 查询表单实例 |
| | | const dialogRef = ref(null) // 弹框实例 |
| | | const dialogVisible = ref(false) |
| | |
| | | |
| | | // 删除 |
| | | async function handleDelete(row) { |
| | | const tips = row ? '该条' : '选中的项' |
| | | await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { |
| | | await ElMessageBox.confirm('确认删除该条记录吗?', '提示', { |
| | | type: 'warning', |
| | | customClass: 'gd-confirm-custom', |
| | | confirmButtonClass: 'gd-confirm-button', |
| | | cancelButtonClass: 'gd-confirm-cancel-button', |
| | | }) |
| | | const ids = row ? row.id : selectedIds.value.join(',') |
| | | await gdDataEvaluationRemoveApi({ ids }) |
| | | await gdDataEvaluationRemoveApi({ ids: row.id }) |
| | | ElMessage.success('删除成功') |
| | | selectedIds.value = [] |
| | | getList() |
| | | } |
| | | |
| | | // 勾选值设置 |
| | | function handleSelectionChange(rows) { |
| | | selectedIds.value = rows.map(item => item.id) |
| | | } |
| | | |
| | | |
| | | // 获取部门树 |
| | | function getDeptTreeFun() { |
| | |
| | | </div> |
| | | <template #footer> |
| | | <template v-if="detailDemandStatus === '1' && !requesterProvider"> |
| | | <el-button class="save-btn" color="#4C34FF" @click="rejectTheApplication">拒绝申请</el-button> |
| | | <el-button color="#F2F3F5" @click="approvedByTheReview">审核通过</el-button> |
| | | <el-button color="#F2F3F5" @click="rejectTheApplication">拒绝申请</el-button> |
| | | <el-button class="save-btn" color="#4C34FF" @click="approvedByTheReview">审核通过</el-button> |
| | | </template> |
| | | <template v-if="detailDemandStatus === '2'"> |
| | | <el-button class="save-btn" color="#4C34FF" @click="downloadAllFiles">全部下载</el-button> |
| | |
| | | </el-form> |
| | | <template #footer v-if="!dialogReadonly"> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | color="#F2F3F5" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | @click="handleSubmit" |
| | | > |
| | | 保存 |
| | | </el-button> |
| | | <el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | <el-button class="save-btn" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="handleApply">申请</el-button> |
| | | |
| | | </template> |
| | | </el-dialog> |
| | |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="需求名称" prop="demandName"> |
| | | <el-input |
| | | class="gd-input" |
| | | class="gd-input gray" |
| | | v-model="searchParams.demandName" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | |
| | | <el-form-item label="需求状态" prop="demandStatus"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.demandStatus" |
| | | placeholder="请选择" |
| | |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list"> |
| | | <el-table-column label="序号" width="60" align="center"> |
| | | <template #default="scope"> |
| | | {{ ((searchParams.current - 1) * searchParams.size + scope.$index + 1).toString().padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <template #default="scope"> |
| | | {{ ((searchParams.current - 1) * searchParams.size + scope.$index + 1).toString().padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="demandName" show-overflow-tooltip label="需求名称" /> |
| | | <el-table-column prop="demandType" show-overflow-tooltip label="需求类型"> |
| | | <template v-slot="{ row }"> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="contactPerson" show-overflow-tooltip label="需求联系人" /> |
| | | <el-table-column prop="contactPhone" show-overflow-tooltip width="120" label="需求联系人电话" /> |
| | | <el-table-column prop="contactPhone" show-overflow-tooltip width="150" label="需求联系人电话" /> |
| | | <el-table-column prop="contactEmail" show-overflow-tooltip label="需求邮箱" /> |
| | | <el-table-column prop="demandStatus" show-overflow-tooltip label="需求状态"> |
| | | <template v-slot="{ row }"> |
| | |
| | | <el-table-column prop="responsibleDeptName" show-overflow-tooltip label="责任部门" /> |
| | | <el-table-column prop="dataSource" show-overflow-tooltip label="数据来源依据" /> |
| | | <el-table-column prop="demandInfo" show-overflow-tooltip label="需求信息项" /> |
| | | <el-table-column label="操作" class-name="operation-btns" width="130"> |
| | | <el-table-column label="操作" class-name="operation-btns" width="180"> |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <!-- 只对非审批状态显示编辑和删除按钮 --> |
| | | <el-link @click="openForm('edit', row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">编辑</el-link> |
| | | <el-link @click="handleDelete(row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">删除</el-link> |
| | | </template> |
| | | <el-link @click="openForm('view', row)">查看</el-link> |
| | | <!-- 只对非审批状态显示编辑和删除按钮 --> |
| | | <el-link @click="openForm('edit', row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">编辑</el-link> |
| | | <el-link @click="handleDelete(row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | |
| | | // 为每条记录添加部门名称 |
| | | list.value = records.map(item => ({ |
| | | ...item, |
| | | responsibleDeptName: item.responsibleDeptName || getDeptNameById(item.responsibleDeptId, deptTree.value) |
| | | responsibleDeptName: item.responsibleDeptName || getDeptNameById(item.responsibleDeptId, deptTree.value), |
| | | })) |
| | | total.value = res?.data?.data?.total ?? 0 |
| | | } finally { |
| | |
| | | ElMessage.success('删除成功') |
| | | getList() |
| | | } |
| | | |
| | | |
| | | |
| | | // 获取字典 |
| | | function getDictList() { |
| | |
| | | <div class="detail-container"> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">拒绝原因:</span> |
| | | <el-input v-model="reasonForRejection" style="width: 380px" type="textarea" placeholder="请输入" /> |
| | | <el-input v-model="reasonForRejection" style="width: 380px" type="textarea" :rows="4" placeholder="请输入" /> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | |
| | | } |
| | | ) |
| | | |
| | | |
| | | // 确认按钮点击事件 |
| | | const handleConfirm = () => { |
| | | if (!reasonForRejection.value.trim()) { |
| | |
| | | min-width: 80px; |
| | | flex-shrink: 0; |
| | | } |
| | | :deep(.el-textarea__inner) { |
| | | height: 100px !important; |
| | | } |
| | | :deep(.el-textarea__inner) { |
| | | height: 100px !important; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="模糊搜索" prop="patrolTaskName"> |
| | | <el-input |
| | | class="gd-input" |
| | | class="gd-input gray" |
| | | v-model="searchParams.patrolTaskName" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | |
| | | <el-form-item label="巡查任务类型" prop="patrolTaskType"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.patrolTaskType" |
| | | placeholder="请选择" |
| | |
| | | |
| | | <el-form-item label="执行时间" prop="executeTime"> |
| | | <el-date-picker |
| | | class="gd-date-picker" |
| | | class="gd-date-picker gray" |
| | | popper-class="gd-date-picker-popper" |
| | | v-model="dateRange" |
| | | type="daterange" |
| | |
| | | <!-- 巡查报告管理 --> |
| | | <template> |
| | | <basic-container> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <basic-container> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="模糊搜索" prop="nickName"> |
| | | <el-input |
| | | class="gd-input" |
| | | class="gd-input gray" |
| | | v-model="searchParams.nickName" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | |
| | | <el-form-item label="文档类型" prop="resultType"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.resultType" |
| | | placeholder="请选择" |
| | |
| | | </el-form> |
| | | |
| | | <div class="gd-table-toolbar"> |
| | | <el-button :icon="Download" color="#4C34FF" type="primary" @click="handleDownload">文档下载</el-button> |
| | | <el-button :icon="Download" color="#4C34FF" type="primary" @click="handleDownload">文档下载</el-button> |
| | | <el-button :icon="Upload" color="#4C34FF" type="primary" @click="handleUpload">文档上传</el-button> |
| | | </div> |
| | | |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-container" v-loading="loading"> |
| | | <div class="gd-table-content gd-table-content-bg"> |
| | | <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="46" /> |
| | |
| | | <el-table-column prop="attachSize" show-overflow-tooltip label="文档大小" /> |
| | | <el-table-column prop="deptName" show-overflow-tooltip label="文档归属" /> |
| | | <!-- <el-table-column prop="resultType" show-overflow-tooltip label="文档类型" /> --> |
| | | <el-table-column prop="resultType" show-overflow-tooltip label="文档类型"> |
| | | <el-table-column prop="resultType" show-overflow-tooltip label="文档类型"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDictLabel(row.resultType, dictObj.patrolTaskType) }} |
| | | </template> |
| | |
| | | /> |
| | | </div> |
| | | </div> |
| | | <el-dialog class="gd-dialog" append-to-body v-model="isShowEditView" :title="titleTxt" |
| | | :width="pxToRem(800)" :close-on-click-modal="false" :destroy-on-close="true" @close="handleClose"> |
| | | <el-form class="gd-dialog-form" ref="ruleFormRef" :model="editParams" :rules="rules" label-width="140px"> |
| | | <el-form-item label="文档名称" prop="nickName"> |
| | | <el-input v-model="editParams.nickName" /> |
| | | </el-form-item> |
| | | <el-form-item label="文档类型" prop="resultType" v-if="titleTxt === '上传巡查报告'"> |
| | | <el-select |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | v-model="editParams.resultType" |
| | | placeholder="请选择" |
| | | clearable |
| | | <el-dialog |
| | | class="gd-dialog" |
| | | append-to-body |
| | | v-model="isShowEditView" |
| | | :title="titleTxt" |
| | | :width="pxToRem(800)" |
| | | :close-on-click-modal="false" |
| | | :destroy-on-close="true" |
| | | @close="handleClose" |
| | | > |
| | | <el-form class="gd-dialog-form" ref="ruleFormRef" :model="editParams" :rules="rules" label-width="140px"> |
| | | <el-form-item label="文档名称" prop="nickName"> |
| | | <el-input v-model="editParams.nickName" class="gd-input" placeholder="请输入" /> |
| | | </el-form-item> |
| | | <el-form-item label="文档类型" prop="resultType" v-if="titleTxt === '上传巡查报告'"> |
| | | <el-select |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | v-model="editParams.resultType" |
| | | placeholder="请选择" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in dictObj.patrolTaskType" |
| | | :key="item.dictKey" |
| | | :label="item.dictValue" |
| | | :value="item.dictKey" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="上传文件" prop="link" v-if="titleTxt === '上传巡查报告'"> |
| | | {{ uploadName }} |
| | | <el-upload class="avatar-uploader" action="" :show-file-list="false" :before-upload="onUploadFileBefore"> |
| | | <el-button size="small" type="primary">点击上传</el-button> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- </div> --> |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="isShowEditView = false">取消</el-button> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | :loading="submitting" |
| | | :disabled="submitting" |
| | | @click="submit(ruleFormRef)" |
| | | > |
| | | <el-option |
| | | v-for="item in dictObj.patrolTaskType" |
| | | :key="item.dictKey" |
| | | :label="item.dictValue" |
| | | :value="item.dictKey" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="上传文件" prop="link" v-if="titleTxt === '上传巡查报告'"> |
| | | {{ uploadName }} |
| | | <el-upload |
| | | class="avatar-uploader" |
| | | action="" |
| | | :show-file-list="false" |
| | | :before-upload="onUploadFileBefore" |
| | | > |
| | | <el-button size="small" type="primary">点击上传</el-button> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- </div> --> |
| | | <template #footer> |
| | | <el-button color="#F2F3F5" @click="isShowEditView = false">取消</el-button> |
| | | <el-button class="save-btn" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="submit(ruleFormRef)"> |
| | | 保存 |
| | | </el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <PreviewFiles v-model="previewVisible" :src="searchUrl" type="docx"/> |
| | | <!-- <el-image v-if="previewVisibleImg" :src="searchUrl" fit="contain" style="height: 100%;width: 100%" /> --> |
| | | <el-image-viewer |
| | | v-if="previewVisibleImg" |
| | | :url-list="[searchUrl]" |
| | | @close="previewVisibleImg = false" |
| | | ></el-image-viewer> |
| | | </basic-container> |
| | | 保存 |
| | | </el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <PreviewFiles v-model="previewVisible" :src="searchUrl" type="docx" /> |
| | | <!-- <el-image v-if="previewVisibleImg" :src="searchUrl" fit="contain" style="height: 100%;width: 100%" /> --> |
| | | <el-image-viewer |
| | | v-if="previewVisibleImg" |
| | | :url-list="[searchUrl]" |
| | | @close="previewVisibleImg = false" |
| | | ></el-image-viewer> |
| | | </basic-container> |
| | | </template> |
| | | <script setup> |
| | | import { Search, RefreshRight, Download, Upload, Delete } from '@element-plus/icons-vue' |
| | | import { fjPageApi, fjSubmitApi, fjRemoveApi, fjDetailApi, fjUploadApi } from './inspectionRequestApi' |
| | | import { useStore } from 'vuex' |
| | | import { ref, computed, inject, onMounted } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { getDictLabel } from '@ztzf/utils' |
| | | import PreviewFiles from '@/components/PreviewFiles/PreviewFiles.vue' |
| | | import { getDictionaryByCode } from '@/api/system/dictbiz' |
| | | import { Search, RefreshRight, Download, Upload, Delete } from '@element-plus/icons-vue' |
| | | import { fjPageApi, fjSubmitApi, fjRemoveApi, fjDetailApi, fjUploadApi } from './inspectionRequestApi' |
| | | import { useStore } from 'vuex' |
| | | import { ref, computed, inject, onMounted } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { getDictLabel } from '@ztzf/utils' |
| | | import PreviewFiles from '@/components/PreviewFiles/PreviewFiles.vue' |
| | | import { getDictionaryByCode } from '@/api/system/dictbiz' |
| | | |
| | | const store = useStore() |
| | | const userInfo = computed(() => store.getters.userInfo); |
| | | const store = useStore() |
| | | const userInfo = computed(() => store.getters.userInfo) |
| | | |
| | | // 初始化查询参数 |
| | | // 初始化查询参数 |
| | | const initSearchParams = () => ({ |
| | | nickName: '', |
| | | resultType: '', |
| | |
| | | const isShowEditView = ref(false) |
| | | const titleTxt = ref('上传巡查报告') |
| | | const editParams = ref({ |
| | | id:'', |
| | | nickName: '', |
| | | resultType: '', |
| | | link: '', |
| | | id: '', |
| | | nickName: '', |
| | | resultType: '', |
| | | link: '', |
| | | }) |
| | | const ruleFormRef = ref() |
| | | const submitting = ref(false) |
| | | const rules = ref({ |
| | | nickName: [{ required: true, message: '请输入文档名称', trigger: ['blur'] }], |
| | | resultType: [{ required: true, message: '请选择文档类型', trigger: ['change'] }], |
| | | link: [{ required: true, message: '请上传文件', trigger: ['change'] }], |
| | | nickName: [{ required: true, message: '请输入文档名称', trigger: ['blur'] }], |
| | | resultType: [{ required: true, message: '请选择文档类型', trigger: ['change'] }], |
| | | link: [{ required: true, message: '请上传文件', trigger: ['change'] }], |
| | | }) |
| | | |
| | | // 获取字典 |
| | |
| | | }) |
| | | } |
| | | |
| | | // 获取列表 |
| | | // 获取列表 |
| | | async function getList() { |
| | | loading.value = true |
| | | try { |
| | |
| | | // 新增/编辑/查看 弹框 |
| | | function openForm(row) { |
| | | isShowEditView.value = true |
| | | titleTxt.value = '编辑' |
| | | titleTxt.value = '编辑' |
| | | editParams.value.id = row.id |
| | | editParams.value.nickName = row.nickName |
| | | editParams.value.resultType = row.resultType |
| | |
| | | if (!row.link) { |
| | | ElMessage.warning('文件链接不存在') |
| | | return |
| | | } else if (!row.link.includes('docx') && !row.link.includes('pdf') && !row.link.includes('png') && !row.link.includes('jpg')) { |
| | | } else if ( |
| | | !row.link.includes('docx') && |
| | | !row.link.includes('pdf') && |
| | | !row.link.includes('png') && |
| | | !row.link.includes('jpg') |
| | | ) { |
| | | ElMessage.warning(`${fileType}文件格式,可以下载再查看`) |
| | | return |
| | | } else if (row.link.includes('png') || row.link.includes('jpg')) { |
| | |
| | | // 勾选值设置 |
| | | function handleSelectionChange(rows) { |
| | | selectedFiles.value = rows |
| | | selectedIds.value = rows.map((item) => item.id) |
| | | selectedIds.value = rows.map(item => item.id) |
| | | } |
| | | |
| | | // 文档下载 |
| | |
| | | } |
| | | }, index * 300) // 300ms delay between downloads |
| | | }) |
| | | |
| | | } |
| | | |
| | | // 文档上传 |
| | | async function handleUpload() { |
| | | isShowEditView.value = true |
| | | titleTxt.value = '上传巡查报告' |
| | | titleTxt.value = '上传巡查报告' |
| | | } |
| | | |
| | | // 上传文件前处理 |
| | | function onUploadFileBefore(file) { |
| | | // 执行文件上传 |
| | | let data = new FormData(); |
| | | data.append('file', file); |
| | | |
| | | fjUploadApi(data).then(res => { |
| | | if (res.data.code === 200) { |
| | | ElMessage.success('上传成功') |
| | | // 保存文件URL到表单 |
| | | uploadName.value = res.data.data.originalName |
| | | editParams.value.link = res.data.data.link |
| | | } else { |
| | | ElMessage.error(res.msg || '上传失败') |
| | | } |
| | | }) |
| | | |
| | | return false // 阻止组件的默认上传行为 |
| | | // 执行文件上传 |
| | | let data = new FormData() |
| | | data.append('file', file) |
| | | |
| | | fjUploadApi(data).then(res => { |
| | | if (res.data.code === 200) { |
| | | ElMessage.success('上传成功') |
| | | // 保存文件URL到表单 |
| | | uploadName.value = res.data.data.originalName |
| | | editParams.value.link = res.data.data.link |
| | | } else { |
| | | ElMessage.error(res.msg || '上传失败') |
| | | } |
| | | }) |
| | | |
| | | return false // 阻止组件的默认上传行为 |
| | | } |
| | | |
| | | // 保存上传文件数据 |
| | | async function submit(formValidate) { |
| | | if (!formValidate) return |
| | | await formValidate.validate(async (valid, fields) => { |
| | | if (valid) { |
| | | submitting.value = true |
| | | try { |
| | | await fjSubmitApi({ ...editParams.value }) |
| | | ElMessage.success('保存成功') |
| | | isShowEditView.value = false |
| | | getList() |
| | | } finally { |
| | | submitting.value = false |
| | | } |
| | | } |
| | | }) |
| | | if (!formValidate) return |
| | | await formValidate.validate(async (valid, fields) => { |
| | | if (valid) { |
| | | submitting.value = true |
| | | try { |
| | | await fjSubmitApi({ ...editParams.value }) |
| | | ElMessage.success('保存成功') |
| | | isShowEditView.value = false |
| | | getList() |
| | | } finally { |
| | | submitting.value = false |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function handleClose() { |
| | | // 清除表单内容 |
| | | uploadName.value = '' |
| | | editParams.value = { |
| | | id: '', |
| | | nickName: '', |
| | | resultType: '', |
| | | uploadFile: '', |
| | | } |
| | | // 清除表单内容 |
| | | uploadName.value = '' |
| | | editParams.value = { |
| | | id: '', |
| | | nickName: '', |
| | | resultType: '', |
| | | uploadFile: '', |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getDictList() |
| | | getList() |
| | | }) |
| | | |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | </style> |
| | | <style scoped lang="scss"></style> |
| | |
| | | v-model="visible" |
| | | :title="titleEnum[dialogMode]" |
| | | @closed="visible = false" |
| | | :style="{ width: pxToRem(1216) }" |
| | | destroy-on-close |
| | | :close-on-click-modal="false" |
| | | > |
| | |
| | | <div class="leftBox"> |
| | | <!-- 查看模式 --> |
| | | <div class="detail-container" v-if="dialogReadonly"> |
| | | <div class="detail-title">工单详情</div> |
| | | <el-row class="detail-row-view"> |
| | | <el-col :span="12"> |
| | | <div class="label">巡查任务名称</div> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <template v-if="['6', '7', '8'].includes(taskStatus)"> |
| | | <div>任务成功({{ list.length || 0 }}条)</div> |
| | | <div style="display: flex"> |
| | | <div class="detail-title" :style="{ marginTop: pxToRem(10) }">任务成功({{ list.length || 0 }}条)</div> |
| | | <div class="imgBox"> |
| | | <div v-for="item in list"> |
| | | <el-image |
| | | v-if="item.resultUrl" |
| | | :src="item.resultUrl" |
| | | :preview-src-list="[item.resultUrl]" |
| | | fit="cover" |
| | | style="width: 80px; height: 60px" |
| | | preview-teleported |
| | | /> |
| | | </div> |
| | |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="巡查任务描述" prop="taskDesc"> |
| | | <el-input class="gd-input" type="textarea" v-model="formData.taskDesc" placeholder="请输入" clearable /> |
| | | <el-input |
| | | class="gd-input" |
| | | type="textarea" |
| | | :rows="4" |
| | | v-model="formData.taskDesc" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <!-- 地图组件 --> |
| | | <CommonCesiumMap |
| | | ref="mapRef" |
| | | class="leftMap gd-cesium" |
| | | class="gd-cesium" |
| | | :active="visible" |
| | | :flat-mode="false" |
| | | :terrain="true" |
| | | :layer-mode="4" |
| | | :boundary="false" |
| | | :zoomToBoundary="false" |
| | | @ready="() => mapRef.flyBoundary()" |
| | | /> |
| | | </div> |
| | | </div> |
| | |
| | | display: flex; |
| | | gap: 0 20px; |
| | | .leftBox { |
| | | width: 0; |
| | | flex: 1; |
| | | width: 920px; |
| | | .gd-cesium { |
| | | padding-top: 10px; |
| | | width: 100%; |
| | | height: 423px; |
| | | } |
| | | } |
| | | |
| | | .imgBox { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 10px; |
| | | > div { |
| | | width: calc((100% - 40px) / 5); /* 5列布局,减去4个10px间隙 */ |
| | | height: 110px; |
| | | flex-shrink: 0; |
| | | } |
| | | .el-image { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <basic-container> |
| | | <el-tabs class="gd-tabs" v-model="activeName" @tab-click="tabsClick"> |
| | | <el-tab-pane label="全部 " name="all"></el-tab-pane> |
| | | <el-tab-pane label="我的任务工单" name="my"></el-tab-pane> |
| | | <el-tab-pane label="我的巡查任务" name="my"></el-tab-pane> |
| | | </el-tabs> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="任务名称" prop="patrolTaskName"> |
| | | <el-input |
| | | class="gd-input" |
| | | class="gd-input gray" |
| | | v-model="searchParams.patrolTaskName" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | |
| | | <el-form-item label="任务类型" prop="patrolTaskType"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.patrolTaskType" |
| | | placeholder="请选择" |
| | |
| | | |
| | | <el-form-item label="任务状态" prop="taskStatus"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.taskStatus" |
| | | placeholder="请选择" |
| | |
| | | |
| | | <el-form-item label="执行时间" prop="executeTime"> |
| | | <el-date-picker |
| | | class="gd-date-picker" |
| | | class="gd-date-picker gray" |
| | | popper-class="gd-date-picker-popper" |
| | | v-model="dateRange" |
| | | type="daterange" |
| | |
| | | </div> |
| | | |
| | | <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" /> |
| | | <ViewDiaLog ref="viewDiaLogRef" @success="getList" @refusalAccept="refusalAccept" v-if="viewDiaLogVisible" v-model="viewDiaLogVisible" /> |
| | | <ViewDiaLog |
| | | ref="viewDiaLogRef" |
| | | @success="getList" |
| | | @refusalAccept="refusalAccept" |
| | | v-if="viewDiaLogVisible" |
| | | v-model="viewDiaLogVisible" |
| | | /> |
| | | </basic-container> |
| | | </template> |
| | | <script setup> |
| | |
| | | function refusalAccept(row) { |
| | | dialogVisible.value = true |
| | | nextTick(() => { |
| | | dialogRef.value?.open({ mode:'edit', row }) |
| | | dialogRef.value?.open({ mode: 'edit', row }) |
| | | }) |
| | | } |
| | | |
| | |
| | | :width="pxToRem(800)" :close-on-click-modal="false" :destroy-on-close="true" @close="handleClose"> |
| | | <el-form class="gd-dialog-form" ref="ruleFormRef" :model="editParams" :rules="rules" label-width="140px"> |
| | | <el-form-item label="营业收入" prop="operatingIncome"> |
| | | <el-input v-model="editParams.operatingIncome" /> |
| | | <el-input class="gd-input" v-model="editParams.operatingIncome" /> |
| | | </el-form-item> |
| | | <el-form-item label="综合总成本费用" prop="totalCost"> |
| | | <el-input v-model="editParams.totalCost" /> |
| | | <el-input class="gd-input" v-model="editParams.totalCost" /> |
| | | </el-form-item> |
| | | <el-form-item label="净利润" prop="netProfit"> |
| | | <el-input v-model="editParams.netProfit" /> |
| | | <el-input class="gd-input" v-model="editParams.netProfit" /> |
| | | </el-form-item> |
| | | <el-form-item label="财务内部收益率" prop="financialIrr"> |
| | | <el-input v-model="editParams.financialIrr" /> |
| | | <el-input class="gd-input" v-model="editParams.financialIrr" /> |
| | | </el-form-item> |
| | | <el-form-item label="市场空间" prop="marketSpace"> |
| | | <el-input v-model="editParams.marketSpace" /> |
| | | <el-input class="gd-input" v-model="editParams.marketSpace" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- </div> --> |
| | |
| | | > |
| | | <div class="content" style="display: flex"> |
| | | <div class="processBox" v-if="dialogMode !== 'add' && processList.length"> |
| | | <el-timeline> |
| | | <el-timeline class="gd-timeline"> |
| | | <el-timeline-item |
| | | v-for="(activity, index) in processList" |
| | | :key="index" |
| | |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="工单备注" prop="remark"> |
| | | <el-input class="gd-input" type="textarea" v-model="formData.remark" placeholder="请输入" clearable /> |
| | | <el-input |
| | | class="gd-input" |
| | | type="textarea" |
| | | :rows="4" |
| | | v-model="formData.remark" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <el-table-column prop="devicePayload" label="设备负载" /> |
| | | </el-table> |
| | | </template> |
| | | <div v-else>请先选择设备需求并在地图上绘制工单范围</div> |
| | | <div v-else class="tipSelect">请先选择设备需求并在地图上绘制工单范围</div> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | |
| | | .processBox { |
| | | width: 312px; |
| | | .el-timeline { |
| | | padding-left: 100px; |
| | | } |
| | | .item-content { |
| | | position: relative; |
| | | .flowName { |
| | | width: 80px; |
| | | position: absolute; |
| | | left: -100px; |
| | | top: 0; |
| | | left: -120px; |
| | | top: 0px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .setHeight { |
| | | //max-height: 300px; |
| | | //min-height: 200px; |
| | | .tipSelect { |
| | | text-align: center; |
| | | height: 200px; |
| | | line-height: 200px; |
| | | } |
| | | </style> |
| | |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="工单名称" prop="workOrderName"> |
| | | <el-input |
| | | class="gd-input" |
| | | class="gd-input gray" |
| | | v-model="searchParams.workOrderName" |
| | | placeholder="请输入" |
| | | clearable |
| | |
| | | |
| | | <el-form-item label="工单类型" prop="workOrderType"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.workOrderType" |
| | | placeholder="请选择" |
| | |
| | | |
| | | <el-form-item label="工单状态" prop="workOrderStatus"> |
| | | <el-select |
| | | class="gd-select" |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.workOrderStatus" |
| | | placeholder="请选择" |
| | |
| | | |
| | | <el-form-item label="执行时间" prop="executeTime"> |
| | | <el-date-picker |
| | | class="gd-date-picker" |
| | | class="gd-date-picker gray" |
| | | popper-class="gd-date-picker-popper" |
| | | v-model="dateRange" |
| | | type="daterange" |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="请假理由"> |
| | | <el-input :disabled="true" type="textarea" v-model="form.reason" /> |
| | | <el-input :disabled="true" type="textarea" :rows="4" v-model="form.reason" /> |
| | | </el-form-item> |
| | | </el-card> |
| | | <el-card shadow="hover"> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="请假理由"> |
| | | <el-input :disabled="true" type="textarea" v-model="form.reason" /> |
| | | <el-input :disabled="true" type="textarea" :rows="4" v-model="form.reason" /> |
| | | </el-form-item> |
| | | <el-form-item label="批复意见"> |
| | | <el-input type="textarea" v-model="form.comment" /> |
| | | <el-input type="textarea" :rows="4" v-model="form.comment" /> |
| | | </el-form-item> |
| | | </el-card> |
| | | <el-card shadow="hover"> |
| | |
| | | import {request} from "@/utils/index.js"; |
| | | export const getList = (data) => { |
| | | import { request } from "@/utils/requestGd/index.js" |
| | | import website from '@/config/website' |
| | | |
| | | |
| | | // 工单用户登录接口 |
| | | export const ticketLoginInterfaceApi = (tenantId, deptId, roleId, username, password, type, key, code) => { |
| | | return request({ |
| | | url: '/drone-device-core/jobEvent/eventPage', |
| | | url: '/blade-auth/oauth/token', |
| | | method: 'post', |
| | | data, |
| | | header: { |
| | | 'Tenant-Id': tenantId, |
| | | 'Dept-Id': website.switchMode ? deptId : '', |
| | | 'Role-Id': website.switchMode ? roleId : '', |
| | | 'Captcha-Key': key, |
| | | 'Captcha-Code': code, |
| | | }, |
| | | params: { |
| | | tenantId, |
| | | username, |
| | | password, |
| | | grant_type: 'password', |
| | | scope: 'all', |
| | | type, |
| | | }, |
| | | }) |
| | | } |
| | | // 获取状态统计数据 |
| | | // 获取工单列表 |
| | | export const getGdList = data => { |
| | | return request({ |
| | | url: '/drone-gd/workOrder/gdClueEvent/list', |
| | | method: 'get', |
| | | data, |
| | | }); |
| | | }; |
| | | // 获取详情 |
| | | export const getGddetailedData = data => { |
| | | return request({ |
| | | url: '/drone-gd/workOrder/gdClueEvent/detail', |
| | | method: 'get', |
| | | data, |
| | | }); |
| | | }; |
| | | // 获取数量 |
| | | export const getstatusCount = (params) => { |
| | | return request({ |
| | | url: '/drone-device-core/jobEvent/getstatusCount', |
| | | url: '/drone-gd/workOrder/gdClueEvent/count', |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| | | |
| | | export const getStepInfo = (eventNum) => { |
| | | // 退回工单 |
| | | export const backGdApi = (data) => { |
| | | return request({ |
| | | url: '/drone-device-core/jobEvent/getStepInfo', |
| | | method: 'get', |
| | | params: { eventNum } |
| | | }) |
| | | } |
| | | |
| | | // 修改接口:处理待审核状态,动态构建 FormData 提交 |
| | | export const flowEvent = (data, file) => { |
| | | const formData = new FormData() |
| | | |
| | | // 动态添加非空字段到 FormData |
| | | Object.entries(data).forEach(([key, value]) => { |
| | | if (value !== undefined && value !== null) { |
| | | formData.append(key, value) |
| | | } |
| | | }) |
| | | |
| | | // 如果 file 存在,则添加到 FormData |
| | | if (file) { |
| | | formData.append('file', file) |
| | | } |
| | | for (let [key, value] of formData.entries()) { |
| | | console.log(key, value) |
| | | } |
| | | console.log('formData',formData) |
| | | return request({ |
| | | url: '/drone-device-core/jobEvent/flowEvent', |
| | | url: '/drone-gd/workOrder/gdClueEvent/handle', |
| | | method: 'post', |
| | | data: formData, |
| | | headers: { |
| | | 'Content-Type': 'multipart/form-data', // 设置为表单数据格式 |
| | | }, |
| | | }) |
| | | } |
| | | |
| | | // 新增接口:获取工单详细信息 |
| | | export const getTicketInfo = (id) => { |
| | | return request({ |
| | | url: '/drone-device-core/jobEvent/getTicketInfo', |
| | | method: 'get', |
| | | params: { id }, // 使用工单 ID 查询 |
| | | data, |
| | | }) |
| | | } |
| | |
| | | |
| | | <script setup> |
| | | import { getAssetsImage } from "@/utils/index.js"; |
| | | import {ticketLoginInterfaceApi} from '@/api/work/index1.js' |
| | | import {ticketLoginInterfaceApi} from '@/api/work/index.js' |
| | | import md5 from "js-md5"; |
| | | import { loginByUsername } from "@/api/user/index.js"; |
| | | import { useUserStore, useLocationStore } from "@/store/index.js"; |
| | |
| | | <view class="page-wrap"> |
| | | <view class="pageUser"> |
| | | <view class="userBox"> |
| | | <view class="flex items-center pb-30rpx pl-30rpx pr-20rpx"> |
| | | <view class="flex items-center pb-30rpx pl-30rpx pr-20rpx userStyle"> |
| | | <view class="mr-20rpx"> |
| | | <u-avatar :src="user.avatar || defaultAvatar" size="70" /> |
| | | </view> |
| | |
| | | }); |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .userStyle { |
| | | padding-top: 192rpx; |
| | | } |
| | | .page-wrap { |
| | | width: 100%; |
| | | height: 100%; |
| | |
| | | background-size: 100% ; |
| | | } |
| | | .userBox { |
| | | padding-top: 212rpx; |
| | | //padding-top: 212rpx; |
| | | } |
| | | .userName { |
| | | font-weight: 700; |
| | |
| | | display: flex; |
| | | justify-content: space-between; |
| | | padding: 0 24rpx; |
| | | margin-top: 24rpx; |
| | | |
| | | .message, |
| | | .passwordBox { |
| | |
| | | <div class="eventTickets" :style="{ paddingTop: topMargin + 'px' }"> |
| | | |
| | | <div class="searchTop"> |
| | | <up-search placeholder="请输入关键字搜索" :animation="true" v-model="listParams.keyword" :show-action="false"></up-search> |
| | | <up-search placeholder="请输入关键字搜索" :animation="true" v-model="listParams.keyword" :show-action="false" @search="handleSearch"></up-search> |
| | | </div> |
| | | <div class="listBox"> |
| | | <div class="tabs-container"> |
| | |
| | | <script setup> |
| | | |
| | | import { useUserStore } from '@/store/index.js' |
| | | import {getGdList,getstatusCount} from '/src/api/work/index1.js' |
| | | import {getGdList,getstatusCount} from '/src/api/work/index.js' |
| | | import dayjs from 'dayjs'; |
| | | import { getStatusBarHeight } from '@/utils/common'; |
| | | const userStore = useUserStore() |
| | |
| | | name: '全部工单', |
| | | key: 'all', |
| | | badge: { |
| | | value: 0 |
| | | value: 0, |
| | | showZero: true |
| | | }, |
| | | status: null |
| | | |
| | | }, |
| | | { |
| | | name: '我的工单', |
| | | key: 'myTickets', |
| | | badge: { |
| | | value: 0 |
| | | value: 0, |
| | | showZero: true |
| | | } |
| | | } |
| | | |
| | |
| | | return dayjs(dateString).format('MM/DD HH:mm'); |
| | | }; |
| | | const listParams = ref({ |
| | | status: null, |
| | | |
| | | current: 1, |
| | | size: 12, |
| | | source: 1, |
| | |
| | | const params = { |
| | | current: listParams.value.current, |
| | | size: listParams.value.size, |
| | | // event_name:listParams.value.keyword, |
| | | keyword:listParams.value.keyword, |
| | | onlyMine:currentTab.value=== 'myTickets' ? 1 : 0 |
| | | } |
| | | getGdList(params).then(res => { |
| | |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | |
| | | |
| | | const getstatusCountData=()=>{ |
| | | getstatusCount().then(res=>{ |
| | | const params={ |
| | | keyword:listParams.value.keyword, |
| | | } |
| | | getstatusCount(params).then(res=>{ |
| | | const response = res.data.data |
| | | const { totalCount,myCount } = response |
| | | tabList.value.forEach(tab=>{ |
| | | |
| | | if(tab.key === 'all'){ |
| | | tab.badge.value = totalCount || 0 |
| | | tab.badge.showZero = true |
| | | |
| | | }else if(tab.key === 'myTickets'){ |
| | | tab.badge.value = myCount || 0 |
| | | }else{ |
| | | tab.badge.value=statusCount[String(tab.status)] || 0 |
| | | tab.badge.showZero = true |
| | | } |
| | | }) |
| | | |
| | |
| | | |
| | | const handleClick = (item) => { |
| | | currentTab.value = item.key |
| | | listParams.value.status = item.status |
| | | |
| | | listParams.value.current = 1 |
| | | hasMore.value = true |
| | | dataList.value = [] |
| | |
| | | url: `/subPackages/workDetail/index?id=${val.id}`, |
| | | }) |
| | | } |
| | | |
| | | // 搜索功能 |
| | | const handleSearch = () => { |
| | | listParams.value.current = 1 |
| | | hasMore.value = true |
| | | dataList.value = [] |
| | | getDataList() |
| | | getstatusCountData() |
| | | } |
| | | const topMargin = getStatusBarHeight() |
| | | onShow(() => { |
| | | listParams.value.current = 1 |
| | |
| | | |
| | | .detailBox { |
| | | position: absolute; |
| | | top: 180rpx; |
| | | // top: 180rpx; |
| | | // margin-top: 40rpx; |
| | | width: 702rpx; |
| | | |
| | |
| | | <script setup> |
| | | // import { getShowImg, getSmallImg } from '@/utils/util' |
| | | import { ref, computed } from 'vue' |
| | | import {getGddetailedData,backGdApi} from '/src/api/work/index1.js' |
| | | import {getGddetailedData,backGdApi} from '/src/api/work/index.js' |
| | | import dayjs from 'dayjs' |
| | | const formatDate = dateString => { |
| | | return dayjs(dateString).format('MM/DD HH:mm') |
| | |
| | | .workDetailContainer { |
| | | // 添加导航栏高度的padding-top,避免内容被遮挡 |
| | | padding-top: 88rpx; |
| | | // 分享按钮样式 |
| | | :deep(){ |
| | | .u-navbar__content{ |
| | | background: url("https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png") no-repeat !important; |
| | | background-size: 100%!important; |
| | | height: 88rpx !important; |
| | | } |
| | | } // 分享按钮样式 |
| | | .share-btn { |
| | | width: 40rpx; |
| | | height: 40rpx; |
| | |
| | | background-position: center; |
| | | } |
| | | .detailTop { |
| | | // #ifdef APP-PLUS |
| | | padding-top: 60rpx; |
| | | // #endif |
| | | .image-container { |
| | | position: relative; |
| | | width: 100%; |
| | |
| | | width: 5px !important; |
| | | } |
| | | } |
| | | .detailTitle { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | width: 100%; |
| | | height: 60rpx; |
| | | line-height: 60rpx; |
| | | background: rgba(7, 7, 7, 0.4); |
| | | } |
| | | |
| | | .titleText { |
| | | display: flex; |
| | | width: 100%; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | color: #fff; |
| | | |
| | | .itemName, |
| | | .itemTime { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 28rpx; |
| | | color: #ffffff; |
| | | } |
| | | .itemName { |
| | | padding-left: 20rpx; |
| | | } |
| | | .itemTime { |
| | | padding-right: 20rpx; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | color: #1d6fe9; |
| | | text-decoration: underline; |
| | | text-align: right; |
| | | //white-space: nowrap; |
| | | ///* 禁止换行 */ |
| | | //overflow: hidden; |
| | | //text-overflow: ellipsis; |
| | | // max-width: 74%; |
| | | |
| | | padding-top: 1px; |
| | | padding-left: 5px; |
| | | padding-right: 2px; |
| | |
| | | import addSvg from '@/static/images/add.png' |
| | | import droneSvg from '@/static/images/drone.png' |
| | | import { aircraftInfoPageInfoOfMyApi } from '@/api/index.js' |
| | | |
| | | // 获取store中的数据 字典 |
| | | import { useAppStore, useUserStore } from "@/store"; |
| | | const appStore = useAppStore() |
| | | |
| | | const equipmentList = ref([]) |
| | | const noticeTitle = ref('') |
| | | const formParams = ref({ |
| | |
| | | try { |
| | | const res = await aircraftInfoPageInfoOfMyApi(formParams.value) |
| | | const newData = res.data.data.records || [] |
| | | // 处理type 字典 |
| | | newData.forEach(item => { |
| | | item.type = appStore.getProType.find(type => type.value === item.type)?.label || '暂无' |
| | | }) |
| | | // 如果是第一页,直接替换数据;否则追加数据 |
| | | if (formParams.value.current === 1) { |
| | | equipmentList.value = newData |
| | |
| | | </view> |
| | | <view class="right"> |
| | | <view class="r-top">{{ item.title }}</view> |
| | | <view class="r-middle">{{ item.description || '暂无描述' }}</view> |
| | | <view class="r-middle">{{ item.noticeDesc || '暂无描述' }}</view> |
| | | <view class="r-bottom">{{ item.time || '暂无' }}</view> |
| | | </view> |
| | | </view> |
| | |
| | | size: 10, |
| | | noticeType: 2, |
| | | noticeTitle: noticeTitle.value, |
| | | isAsc: true |
| | | }) |
| | | |
| | | const tabClick = (val) => { |
| | |
| | | formParams.value.noticeType = 2 |
| | | } else { |
| | | formParams.value.noticeType = 1 |
| | | } |
| | | } |
| | | formParams.value.current = 1 |
| | | announcementList.value = [] |
| | | getSysNoticeList() |
| | |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | |
| | | :deep(.u-search) { |
| | | padding: 10px 20px; |
| | | height: 68rpx; |
| | |
| | | |
| | | .tabs-container >>> .u-tabs__nav { |
| | | width: auto !important; |
| | | } |
| | | } |
| | | .content { |
| | | width: 100%; |
| | | height: 0; |
| | |
| | | .r-bottom { |
| | | font-weight: 400; |
| | | font-size: 13px; |
| | | color: #86909C; |
| | | color: #86909C; |
| | | margin-top: 10rpx; |
| | | } |
| | | } |
| | |
| | | import docSvg from '@/static/images/doc.png' |
| | | import lbBottomPng from '@/static/images/lb_bottom.png' |
| | | import { sysNoticePageInfoApi, droneFlightTaskApi } from '@/api/index' |
| | | import { flightTaskApi,flightRulesApi,flightModeApi,flightPlanApi,flyActivityStatusApi,proTypeApi} from '@/api/index' |
| | | |
| | | import { useAppStore } from "@/store"; |
| | | const appStore = useAppStore() |
| | | |
| | | const lbList = reactive([]); |
| | | // lbPng 轮播图 5次 |
| | | for (let i = 0; i < 5; i++) { |
| | |
| | | announcementList.value = res.data.data.records.map(item => ({ |
| | | ...item, |
| | | title: item.taskName, |
| | | description: item.remark, |
| | | description: item.noticeDesc, |
| | | time: item.createTime, |
| | | num: item.num, |
| | | like: item.like, |
| | |
| | | current: 1, |
| | | size: 3, |
| | | noticeType: val, |
| | | isAsc: true |
| | | }) |
| | | // 只需要取前3条 公告 |
| | | if (val === 1) { |
| | |
| | | }) |
| | | } |
| | | |
| | | // 获取任务类型 |
| | | const actionsFlightTaskType = ref([]) |
| | | function getTaskType() { |
| | | flightTaskApi().then(res => { |
| | | actionsFlightTaskType.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | // 存储到store |
| | | appStore.setTaskType(actionsFlightTaskType.value) |
| | | }) |
| | | } |
| | | // 获取飞行模式 |
| | | const actionsFlightMode = ref([]) |
| | | function getFlightMode() { |
| | | flightModeApi().then(res => { |
| | | actionsFlightMode.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | // 存储到store |
| | | appStore.setFlightMode(actionsFlightMode.value) |
| | | }) |
| | | } |
| | | // 获取飞行规则 |
| | | const actionsFlightRule = ref([]) |
| | | function getFlightRules() { |
| | | flightRulesApi().then(res => { |
| | | actionsFlightRule.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | // 存储到store |
| | | appStore.setFlightRules(actionsFlightRule.value) |
| | | }) |
| | | } |
| | | // 获取飞行计划 |
| | | const actionsPlanType = ref([]) |
| | | function getFlightPlan() { |
| | | flightPlanApi().then(res => { |
| | | actionsPlanType.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | // 存储到store |
| | | appStore.setFlightPlan(actionsPlanType.value) |
| | | }) |
| | | } |
| | | // 获取审批状态 |
| | | const flyActivityStatus = ref([]) |
| | | function getFlyActivityStatus() { |
| | | flyActivityStatusApi().then(res => { |
| | | flyActivityStatus.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | // 存储到store |
| | | appStore.setFlyActivityStatus(flyActivityStatus.value) |
| | | }) |
| | | } |
| | | |
| | | // 获取飞行器类型 |
| | | const typeList = ref([]) |
| | | function getProTypeApi() { |
| | | proTypeApi().then(res => { |
| | | typeList.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | // 存储到store |
| | | appStore.setProType(typeList.value) |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getFlightAirspaceList() |
| | | getSysNoticeList(2) |
| | | getSysNoticeList(1) |
| | | |
| | | // 获取字典 |
| | | getTaskType() |
| | | getFlightMode() |
| | | getFlightRules() |
| | | getFlightPlan() |
| | | getFlyActivityStatus() |
| | | getProTypeApi() |
| | | }) |
| | | </script> |
| | | |
| | |
| | | justify-content: space-between; |
| | | font-weight: 400; |
| | | font-size: 13px; |
| | | color: #86909C; |
| | | color: #86909C; |
| | | margin-top: 10rpx; |
| | | } |
| | | } |
| | |
| | | theme: storage.get(THEME_KEY) || 'light', |
| | | deviceUpdateKey: 0, //设备刷新key |
| | | jobUpdateKey: 0, //任务刷新key |
| | | |
| | | // 字典 |
| | | taskType: [], // 任务类型 |
| | | flightMode: [], // 飞行模式 |
| | | flightRules: [], // 飞行规则 |
| | | flightPlan: [], // 飞行计划 |
| | | flyActivityStatus: [], // 飞行活动状态 |
| | | proType: [], // 飞行器类型 |
| | | }), |
| | | getters: { |
| | | getSystemInfo (state) { |
| | |
| | | }, |
| | | getTheme (state) { |
| | | return state.theme |
| | | } |
| | | }, |
| | | // 字典 |
| | | getTaskType (state) { |
| | | return state.taskType |
| | | }, |
| | | getFlightMode (state) { |
| | | return state.flightMode |
| | | }, |
| | | getFlightRules (state) { |
| | | return state.flightRules |
| | | }, |
| | | getFlightPlan (state) { |
| | | return state.flightPlan |
| | | }, |
| | | getFlyActivityStatus (state) { |
| | | return state.flyActivityStatus |
| | | }, |
| | | getProType (state) { |
| | | return state.proType |
| | | }, |
| | | }, |
| | | actions: { |
| | | // 设置字典 |
| | | setTaskType (data) { |
| | | this.taskType = data |
| | | }, |
| | | setFlightMode (data) { |
| | | this.flightMode = data |
| | | }, |
| | | setFlightRules (data) { |
| | | this.flightRules = data |
| | | }, |
| | | setFlightPlan (data) { |
| | | this.flightPlan = data |
| | | }, |
| | | setFlyActivityStatus (data) { |
| | | this.flyActivityStatus = data |
| | | }, |
| | | setProType (data) { |
| | | this.proType = data |
| | | }, |
| | | |
| | | |
| | | setSystemInfo (info) { |
| | | this.systemInfo = info |
| | | }, |
| | | setDeviceUpdateKeyAdd () { |
| | | console.log(111, this.deviceUpdateKey + 1) |
| | | this.deviceUpdateKey = this.deviceUpdateKey + 1 |
| | | }, |
| | | setJobUpdateKeyAdd (state, data) { |
| | |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | } |
| | | }) |
| | | |
| | |
| | | @cancel="showPurchaseDate = false" |
| | | /> |
| | | <!-- 所属区域 --> |
| | | <u-cascader |
| | | <u-cascader |
| | | v-model:show="isShowRegion" |
| | | v-model="formParams.regionCode" |
| | | :data="areaData" |
| | |
| | | import { aircraftInfoSaveApi,uploadFileApi, areaDataApi, proTypeApi, manufacturerInfoApi } from '@/api/index' |
| | | import { ref, computed, onMounted } from 'vue' |
| | | import dayjs from 'dayjs' |
| | | |
| | | // 获取store中的数据 字典 |
| | | import { useAppStore, useUserStore } from "@/store"; |
| | | const appStore = useAppStore() |
| | | |
| | | const formRef = ref(null); |
| | | const formParams = ref({ |
| | |
| | | isModifiedText: [ |
| | | { required: true, message: '请选择是否改装', trigger: 'change' } |
| | | ], |
| | | type: [ |
| | | { required: true, message: '请选择飞行器类型', trigger: 'change' } |
| | | ], |
| | | |
| | | }) |
| | | // 是否改装 |
| | | const actionsModified = ref([ |
| | |
| | | const findRegionNamesByCodes = (codes, areaData) => { |
| | | const result = [] |
| | | let currentData = areaData |
| | | |
| | | |
| | | for (const code of codes) { |
| | | // 转换为字符串比较(因为code可能是字符串类型) |
| | | const codeStr = code.toString() |
| | | const item = currentData.find(item => item.code === codeStr) |
| | | |
| | | |
| | | if (!item) { |
| | | console.warn(`未找到code为 ${codeStr} 的行政区划`) |
| | | break |
| | | } |
| | | |
| | | |
| | | result.push(item.name) |
| | | currentData = item.children || [] |
| | | } |
| | | |
| | | |
| | | return result |
| | | } |
| | | |
| | | // 所属区域确认 |
| | | const onRegionConfirm = (e) => { |
| | | console.log(e,'888') |
| | | formParams.value.region = e[2] || '' // 用逗号分隔的区域码 |
| | | // 通过arrRegion的数组值为[36,3608,360824] 从areaData里面反查出名称 |
| | | const regionNames = findRegionNamesByCodes(e, areaData.value) |
| | | console.log(regionNames, '77777') |
| | | formParams.value.regionText = regionNames.join('-') || '' // 用连字符连接的区域名称 |
| | | isShowRegion.value = false |
| | | } |
| | |
| | | formParams.value.manufacturerText = selected.label |
| | | showManufacturer.value = false |
| | | } |
| | | // 飞行器型号 |
| | | // 飞行器类型 |
| | | const showType = ref(false); |
| | | const typeList = ref([]) |
| | | // 选择飞行器型号 |
| | | const typeList = ref(appStore.getProType) |
| | | // 选择飞行器类型 |
| | | const onPickerConfirmType = (e) => { |
| | | const selected = e.value[0] |
| | | formParams.value.type = selected.value |
| | | console.log(formParams.value.type,'6666') |
| | | formParams.value.typeText = selected.label |
| | | showType.value = false |
| | | } |
| | |
| | | // 获取上传的文件对象 |
| | | const file = event.file; |
| | | console.log('上传的文件:', file); |
| | | |
| | | |
| | | // 显示加载提示 |
| | | uni.showLoading({ |
| | | title: '上传中...' |
| | | }); |
| | | |
| | | |
| | | // 准备上传参数 |
| | | const uploadParams = { |
| | | name: 'file', // 服务器端接收文件的字段名 |
| | | file: file, // 传入文件对象 |
| | | filePath: file.path || file.url, // 文件路径 |
| | | }; |
| | | |
| | | |
| | | // 调用上传文件接口 |
| | | uploadFileApi(uploadParams).then(res => { |
| | | uni.hideLoading(); |
| | | |
| | | |
| | | console.log('上传成功结果:', res); |
| | | |
| | | |
| | | // 根据接口返回的数据结构处理结果 |
| | | if (res.data && res.data.code === 200) { |
| | | // 假设接口返回的数据结构是 { url, fileName } 等 |
| | | const uploadResult = res.data.data; |
| | | |
| | | |
| | | // 更新表单数据,将上传结果展示在input内 |
| | | formParams.value.caacRegistrationCodeText = uploadResult.fileName || uploadResult.url || '文件上传成功'; |
| | | |
| | | |
| | | // 可以将完整的上传信息保存到表单中,以便提交时使用 |
| | | formParams.value.caacRegistrationCode= uploadResult.fileUrl || '文件上传成功'; |
| | | |
| | | |
| | | uni.showToast({ |
| | | title: '上传成功', |
| | | icon: 'success' |
| | |
| | | // 获取上传的文件对象 |
| | | const file = event.file; |
| | | console.log('上传的文件:', file); |
| | | |
| | | |
| | | // 显示加载提示 |
| | | uni.showLoading({ |
| | | title: '上传中...' |
| | | }); |
| | | |
| | | |
| | | // 准备上传参数 |
| | | const uploadParams = { |
| | | name: 'file', // 服务器端接收文件的字段名 |
| | | file: file, // 传入文件对象 |
| | | filePath: file.path || file.url, // 文件路径 |
| | | }; |
| | | |
| | | |
| | | // 调用上传文件接口 |
| | | uploadFileApi(uploadParams).then(res => { |
| | | uni.hideLoading(); |
| | | |
| | | |
| | | console.log('上传成功结果:', res); |
| | | |
| | | |
| | | // 根据接口返回的数据结构处理结果 |
| | | if (res.data && res.data.code === 200) { |
| | | // 假设接口返回的数据结构是 { url, fileName } 等 |
| | | const uploadResult = res.data.data; |
| | | |
| | | |
| | | // 更新表单数据,将上传结果展示在input内 |
| | | formParams.value.deviceImageText = uploadResult.fileName || uploadResult.url || '文件上传成功'; |
| | | |
| | | |
| | | // 可以将完整的上传信息保存到表单中,以便提交时使用 |
| | | formParams.value.deviceImage= uploadResult.fileUrl || '文件上传成功'; |
| | | |
| | | |
| | | uni.showToast({ |
| | | title: '上传成功', |
| | | icon: 'success' |
| | |
| | | } |
| | | } |
| | | // 获取飞行器类型 |
| | | function getProTypeApi() { |
| | | proTypeApi().then(res => { |
| | | typeList.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel, |
| | | value: item.dictValue |
| | | })) |
| | | }) |
| | | } |
| | | // function getProTypeApi() { |
| | | // proTypeApi().then(res => { |
| | | // typeList.value = res.data.data.map(item => ({ |
| | | // ...item, |
| | | // label: item.dictLabel, |
| | | // value: item.dictValue |
| | | // })) |
| | | // }) |
| | | // } |
| | | // 获取无人机厂商 |
| | | function getManufacturerInfoApi() { |
| | | manufacturerInfoApi({ |
| | |
| | | }) |
| | | } |
| | | onMounted(async () => { |
| | | getProTypeApi() |
| | | getManufacturerInfoApi() |
| | | // 动态从外部URL导入xzqhData,确保在使用前已初始化 |
| | | // 注意:直接动态导入外部URL可能会有跨域或构建问题,建议检查服务器CORS设置 |
| | |
| | | display: flex; |
| | | flex-direction: column; |
| | | // padding: 24rpx; |
| | | |
| | | |
| | | .select-wrapper { |
| | | position: relative; |
| | | width: 100%; |
| | | |
| | | |
| | | .select-icon { |
| | | position: absolute; |
| | | right: 20rpx; |
| | |
| | | font-size: 24rpx; |
| | | pointer-events: none; |
| | | } |
| | | } |
| | | |
| | | :deep(.u-toolbar__wrapper__confirm) { |
| | | color: #1D6FE9; |
| | | } |
| | | |
| | | .upload { |
| | |
| | | border-radius: 8rpx 8rpx 8rpx 8rpx; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | |
| | | :deep(.u-form-item) { |
| | | margin-bottom: 20rpx; |
| | | padding: 16rpx 24rpx 18rpx 24rpx; |
| | |
| | | border-radius: 8rpx; |
| | | padding: 0 20rpx; |
| | | background-color: #f5f5f5; |
| | | |
| | | |
| | | &::placeholder { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | |
| | | color: #D2D2D2; |
| | | } |
| | | } |
| | | |
| | | |
| | | .clickable-input { |
| | | width: 100%; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | |
| | | :deep(.u-form-item__label) { |
| | | margin-bottom: 20rpx; |
| | | // font-weight: bold; |
| | |
| | | font-size: 30rpx; |
| | | color: #222324; |
| | | } |
| | | |
| | | |
| | | :deep(.u-form-item__required) { |
| | | color: #FF2600; |
| | | margin-right: 8rpx; |
| | |
| | | <template> |
| | | <view class="flightApplication-add"> |
| | | |
| | | |
| | | <u-form labelPosition="top" :model="formParams" :rules="rules" ref="formRef"> |
| | | <view class="title form-title">基本信息</view> |
| | | <u-form-item |
| | |
| | | > |
| | | <u-input v-model="formParams.flightEndTime" border="none" placeholder="请选择日期" suffixIcon="calendar"></u-input> |
| | | </u-form-item> |
| | | |
| | | |
| | | <u-form-item |
| | | label="计划类型" |
| | | labelWidth="200rpx" |
| | |
| | | </view> |
| | | </template> |
| | | <script setup> |
| | | import { flightPlanSaveApi, |
| | | flightRoutePageInfoApi, |
| | | aircraftInfoPageInfoOfMyApi, |
| | | pilotInfoPageInfoOfMyApi, |
| | | droneFlightTaskApi, |
| | | uploadFileApi, |
| | | flightTaskApi,flightRulesApi,flightModeApi,flightPlanApi |
| | | import { |
| | | flightPlanSaveApi, |
| | | flightRoutePageInfoApi, |
| | | aircraftInfoPageInfoOfMyApi, |
| | | pilotInfoPageInfoOfMyApi, |
| | | droneFlightTaskApi, |
| | | uploadFileApi |
| | | } from '@/api/index' |
| | | import { ref, computed, onMounted } from 'vue' |
| | | import dayjs from 'dayjs' |
| | | |
| | | // 获取store中的数据 字典 |
| | | import { useAppStore, useUserStore } from "@/store"; |
| | | const appStore = useAppStore() |
| | | |
| | | const formRef = ref(null); |
| | | const formParams = ref({ |
| | |
| | | }) |
| | | // 任务类型 |
| | | const isShowFlightTaskType = ref(false) |
| | | const actionsFlightTaskType = ref([]) |
| | | const actionsFlightTaskType = ref(appStore.getTaskType) |
| | | const onPickerFlightTaskType = (e) => { |
| | | const selected = e.value[0] |
| | | formParams.value.flightTaskType = selected.value |
| | |
| | | |
| | | // 飞行规则 |
| | | const isShowFlightRule = ref(false) |
| | | const actionsFlightRule = ref([]) |
| | | const actionsFlightRule = ref(appStore.getFlightRules) |
| | | const onPickerFlightRule = (e) => { |
| | | const selected = e.value[0] |
| | | formParams.value.flightRule = selected.value |
| | |
| | | } |
| | | // 飞行方式 |
| | | const isShowFlightMode = ref(false) |
| | | const actionsFlightMode = ref([]) |
| | | const actionsFlightMode = ref(appStore.getFlightMode) |
| | | const onPickerFlightMode = (e) => { |
| | | const selected = e.value[0] |
| | | formParams.value.flightMode = selected.value |
| | |
| | | } |
| | | // 计划类型 |
| | | const isShowPlanType = ref(false) |
| | | const actionsPlanType = ref([]) |
| | | const actionsPlanType = ref(appStore.getFlightPlan) |
| | | const onPickerPlanType = (e) => { |
| | | const selected = e.value[0] |
| | | formParams.value.planType = selected.value |
| | |
| | | // 获取上传的文件对象 |
| | | const file = event.file; |
| | | console.log('上传的文件:', file); |
| | | |
| | | |
| | | // 显示加载提示 |
| | | uni.showLoading({ |
| | | title: '上传中...' |
| | | }); |
| | | |
| | | |
| | | // 准备上传参数 |
| | | const uploadParams = { |
| | | name: 'file', // 服务器端接收文件的字段名 |
| | | file: file, // 传入文件对象 |
| | | filePath: file.path || file.url, // 文件路径 |
| | | }; |
| | | |
| | | |
| | | // 调用上传文件接口 |
| | | uploadFileApi(uploadParams).then(res => { |
| | | uni.hideLoading(); |
| | | |
| | | |
| | | console.log('上传成功结果:', res); |
| | | |
| | | |
| | | // 根据接口返回的数据结构处理结果 |
| | | if (res.data && res.data.code === 200) { |
| | | // 假设接口返回的数据结构是 { url, fileName } 等 |
| | | const uploadResult = res.data.data; |
| | | |
| | | |
| | | // 更新表单数据,将上传结果展示在input内 |
| | | formParams.value.tempAirspaceApprovalText = uploadResult.fileName || uploadResult.url || '文件上传成功'; |
| | | |
| | | |
| | | // 可以将完整的上传信息保存到表单中,以便提交时使用 |
| | | formParams.value.tempAirspaceApproval = uploadResult.fileUrl || '文件上传成功'; |
| | | |
| | | |
| | | uni.showToast({ |
| | | title: '上传成功', |
| | | icon: 'success' |
| | |
| | | } |
| | | }) |
| | | } |
| | | // 获取任务类型 |
| | | function getTaskType() { |
| | | flightTaskApi().then(res => { |
| | | actionsFlightTaskType.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | }) |
| | | } |
| | | // 获取飞行模式 |
| | | function getFlightMode() { |
| | | flightModeApi().then(res => { |
| | | actionsFlightMode.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | }) |
| | | } |
| | | // 获取飞行规则 |
| | | function getFlightRules() { |
| | | flightRulesApi().then(res => { |
| | | actionsFlightRule.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | }) |
| | | } |
| | | // 获取飞行计划 |
| | | function getFlightPlan() { |
| | | flightPlanApi().then(res => { |
| | | actionsPlanType.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictValue || '暂无', |
| | | })) |
| | | }) |
| | | } |
| | | onMounted(() => { |
| | | // getProTypeApi() |
| | | getTaskType() |
| | | getFlightMode() |
| | | getFlightRules() |
| | | getFlightPlan() |
| | | // getTaskType() |
| | | // getFlightMode() |
| | | // getFlightRules() |
| | | // getFlightPlan() |
| | | getAircraftInfo() |
| | | getPilotInfo() |
| | | getAirspaceInfo() |
| | |
| | | border-radius: 8rpx 8rpx 8rpx 8rpx; |
| | | // margin-bottom: 20rpx; |
| | | } |
| | | :deep(.u-toolbar__wrapper__confirm) { |
| | | color: #1D6FE9; |
| | | } |
| | | .custom-label { |
| | | .label-tip { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | |
| | | color: #3A3A3A; |
| | | } |
| | | } |
| | | |
| | | |
| | | .attention { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | |
| | | .select-wrapper { |
| | | position: relative; |
| | | width: 100%; |
| | | |
| | | |
| | | .select-icon { |
| | | position: absolute; |
| | | right: 20rpx; |
| | |
| | | border-radius: 8rpx; |
| | | padding: 0 20rpx; |
| | | background-color: #f5f5f5; |
| | | |
| | | |
| | | &::placeholder { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | |
| | | color: #D2D2D2; |
| | | } |
| | | } |
| | | |
| | | |
| | | .clickable-input { |
| | | width: 100%; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | |
| | | :deep(.u-form-item__label) { |
| | | margin-bottom: 20rpx; |
| | | // font-weight: bold; |
| | |
| | | font-size: 30rpx; |
| | | color: #222324; |
| | | } |
| | | |
| | | |
| | | :deep(.u-form-item__required) { |
| | | color: #FF2600; |
| | | margin-right: 8rpx; |
| | |
| | | <!-- 飞行活动申请 --> |
| | | <template> |
| | | <view class="flightApplication-add"> |
| | | <view class="title"> |
| | | 基本信息 |
| | | </view> |
| | | <u-form labelPosition="top" :model="formParams" :rules="rules" ref="formRef"> |
| | | <view class="title form-title">基本信息</view> |
| | | <u-form-item |
| | | label="飞行计划" |
| | | labelWidth="200rpx" |
| | |
| | | > |
| | | <u-input v-model="formParams.flightEndTime" border="none" suffixIcon="calendar"></u-input> |
| | | </u-form-item> |
| | | |
| | | |
| | | <u-form-item |
| | | label="计划类型" |
| | | labelWidth="200rpx" |
| | |
| | | </view> |
| | | </template> |
| | | <script setup> |
| | | import { flightPlanSaveApi, |
| | | flightRoutePageInfoApi, |
| | | aircraftInfoPageInfoOfMyApi, |
| | | pilotInfoPageInfoOfMyApi, |
| | | flightAirspacePageInfoApi, |
| | | uploadFileApi, |
| | | flightTaskApi,flightRulesApi,flightModeApi,flightPlanApi,flightPlanDetailsApi |
| | | import { |
| | | flightPlanDetailsApi, |
| | | flightRoutePageInfoApi, |
| | | aircraftInfoPageInfoOfMyApi, |
| | | pilotInfoPageInfoOfMyApi, |
| | | flightAirspacePageInfoApi, |
| | | } from '@/api/index' |
| | | import { ref, computed, onMounted } from 'vue' |
| | | import dayjs from 'dayjs' |
| | | |
| | | // 获取store中的数据 字典 |
| | | import { useAppStore, useUserStore } from "@/store"; |
| | | const appStore = useAppStore() |
| | | |
| | | const formRef = ref(null); |
| | | const formParams = ref({}) |
| | | const rules = ref({}) |
| | | // 任务类型 |
| | | const isShowFlightTaskType = ref(false) |
| | | const actionsFlightTaskType = ref([]) |
| | | |
| | | const actionsFlightTaskType = ref(appStore.getTaskType) |
| | | |
| | | // 飞行规则 |
| | | const isShowFlightRule = ref(false) |
| | | const actionsFlightRule = ref([]) |
| | | const actionsFlightRule = ref(appStore.getFlightRules) |
| | | |
| | | // 飞行方式 |
| | | const isShowFlightMode = ref(false) |
| | | const actionsFlightMode = ref([]) |
| | | const actionsFlightMode = ref(appStore.getFlightMode) |
| | | |
| | | // 计划类型 |
| | | const isShowPlanType = ref(false) |
| | | const actionsPlanType = ref([]) |
| | | const actionsPlanType = ref(appStore.getFlightPlan) |
| | | |
| | | // 是否显示开始时间选择器 |
| | | const isShowStartTime = ref(false) |
| | | // 是否显示结束时间选择器 |
| | | const isShowEndTime = ref(false) |
| | | const startTime = ref(Date.now()); // 设置默认值为当前时间戳 |
| | | const endTime = ref(Date.now()); // 设置默认值为当前时间戳 |
| | | // const startTime = ref(Date.now()); // 设置默认值为当前时间戳 |
| | | // const endTime = ref(Date.now()); // 设置默认值为当前时间戳 |
| | | |
| | | const onConfirmStartTime = (e) => { |
| | | formParams.value.flightStartTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') |
| | | isShowStartTime.value = false |
| | | } |
| | | const onConfirmEndTime = (e) => { |
| | | formParams.value.flightEndTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') |
| | | isShowEndTime.value = false |
| | | } |
| | | // const onConfirmStartTime = (e) => { |
| | | // formParams.value.flightStartTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') |
| | | // isShowStartTime.value = false |
| | | // } |
| | | // const onConfirmEndTime = (e) => { |
| | | // formParams.value.flightEndTime = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss') |
| | | // isShowEndTime.value = false |
| | | // } |
| | | |
| | | |
| | | |
| | | // 获取飞行器信息 |
| | | const isShowAircraftInfo = ref(false) |
| | | // const isShowAircraftInfo = ref(false) |
| | | const aircraftInfoList = ref([]) |
| | | function getAircraftInfo() { |
| | | aircraftInfoPageInfoOfMyApi({ |
| | |
| | | })) |
| | | }) |
| | | } |
| | | const onPickerAircraftInfo = (e) => { |
| | | const selected = e.value[0] |
| | | formParams.value.aircraftId = selected.value |
| | | formParams.value.aircraftText = selected.label |
| | | isShowAircraftInfo.value = false |
| | | } |
| | | // const onPickerAircraftInfo = (e) => { |
| | | // const selected = e.value[0] |
| | | // formParams.value.aircraftId = selected.value |
| | | // formParams.value.aircraftText = selected.label |
| | | // isShowAircraftInfo.value = false |
| | | // } |
| | | // 获取飞手信息 |
| | | const isShowPilotInfo = ref(false) |
| | | const pilotInfoList = ref([]) |
| | | function getPilotInfo() { |
| | | pilotInfoPageInfoOfMyApi({ |
| | |
| | | }) |
| | | } |
| | | // 获取空域信息 |
| | | const isShowAirspaceInfo = ref(false) |
| | | const airspaceInfoList = ref([]) |
| | | function getAirspaceInfo() { |
| | | flightAirspacePageInfoApi({ |
| | |
| | | }) |
| | | } |
| | | // 获取航线信息 |
| | | const isShowFlightRouteInfo = ref(false) |
| | | const flightRouteInfoList = ref([]) |
| | | function getFlightRouteInfo() { |
| | | flightRoutePageInfoApi({ |
| | |
| | | }) |
| | | } |
| | | |
| | | // 获取任务类型 |
| | | function getTaskType() { |
| | | flightTaskApi().then(res => { |
| | | actionsFlightTaskType.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictCode || '暂无', |
| | | })) |
| | | }) |
| | | } |
| | | // 获取飞行模式 |
| | | function getFlightMode() { |
| | | flightModeApi().then(res => { |
| | | actionsFlightMode.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictCode || '暂无', |
| | | })) |
| | | }) |
| | | } |
| | | // 获取飞行规则 |
| | | function getFlightRules() { |
| | | flightRulesApi().then(res => { |
| | | actionsFlightRule.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictCode || '暂无', |
| | | })) |
| | | }) |
| | | } |
| | | // 获取飞行计划 |
| | | function getFlightPlan() { |
| | | flightPlanApi().then(res => { |
| | | actionsPlanType.value = res.data.data.map(item => ({ |
| | | ...item, |
| | | label: item.dictLabel || '暂无', |
| | | value: item.dictCode || '暂无', |
| | | })) |
| | | }) |
| | | } |
| | | |
| | | onLoad((options) => { |
| | | flightPlanDetailsApi(options.id).then(res => { |
| | | console.log(res.data.data, '789') |
| | | // return |
| | | formParams.value = res.data.data |
| | | formParams.value.routeId = res.data.data.routeInfo.name |
| | | formParams.value.airspaceId = res.data.data.airspaceInfo.taskName |
| | | formParams.value.aircraftId = res.data.data.airspaceInfo.aircraftInfoList.map(item => item.name).join(',') |
| | | formParams.value.pilotId = res.data.data.operatorInfoList.map(item => item.name).join(',') |
| | | formParams.value.flightRule = actionsFlightRule.value.find(item => item.dictValue === res.data.data.flightRule)?.dictLabel || '' |
| | | formParams.value.flightMode = actionsFlightMode.value.find(item => item.dictValue === res.data.data.flightMode)?.dictLabel || '' |
| | | formParams.value.planType = actionsPlanType.value.find(item => item.dictValue === res.data.data.planType)?.dictLabel || '' |
| | | formParams.value.flightTaskType = actionsFlightTaskType.value.find(item => item.dictValue === res.data.data.flightTaskType)?.dictLabel || '' |
| | | const result = res.data.data |
| | | formParams.value = result |
| | | formParams.value.routeId = result.routeInfo.name |
| | | formParams.value.airspaceId = result.airspaceInfo.taskName || '无' |
| | | formParams.value.aircraftId = result.airspaceInfo.aircraftInfoList.map(item => item.name).join(',') || '无' |
| | | formParams.value.pilotId = result.operatorInfoList.map(item => item.name).join(',') || '无' |
| | | // 字典 |
| | | formParams.value.flightRule = actionsFlightRule.value.find(item => item.dictValue === result.flightRule)?.dictLabel || '无' |
| | | formParams.value.flightMode = actionsFlightMode.value.find(item => item.dictValue === result.flightMode)?.dictLabel || '无' |
| | | formParams.value.planType = actionsPlanType.value.find(item => item.dictValue === result.planType)?.dictLabel || '无' |
| | | formParams.value.flightTaskType = actionsFlightTaskType.value.find(item => item.dictValue === result.flightTaskType)?.dictLabel || '无' |
| | | }) |
| | | }) |
| | | onMounted(() => { |
| | | getTaskType() |
| | | getFlightMode() |
| | | getFlightRules() |
| | | getFlightPlan() |
| | | // getAircraftInfo() |
| | | // getPilotInfo() |
| | | // getAirspaceInfo() |
| | | // getFlightRouteInfo() |
| | | getAircraftInfo() |
| | | getPilotInfo() |
| | | getAirspaceInfo() |
| | | getFlightRouteInfo() |
| | | }) |
| | | </script> |
| | | <style scoped lang="scss"> |
| | |
| | | .select-wrapper { |
| | | position: relative; |
| | | width: 100%; |
| | | |
| | | |
| | | .select-icon { |
| | | position: absolute; |
| | | right: 20rpx; |
| | |
| | | border-radius: 8rpx; |
| | | padding: 0 20rpx; |
| | | background-color: #f5f5f5; |
| | | |
| | | |
| | | &::placeholder { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | |
| | | color: #D2D2D2; |
| | | } |
| | | } |
| | | |
| | | |
| | | .clickable-input { |
| | | width: 100%; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | |
| | | :deep(.u-form-item__label) { |
| | | margin-bottom: 20rpx; |
| | | // font-weight: bold; |
| | |
| | | font-size: 30rpx; |
| | | color: #222324; |
| | | } |
| | | |
| | | |
| | | :deep(.u-form-item__required) { |
| | | color: #FF2600; |
| | | margin-right: 8rpx; |
| | |
| | | <u-image :src="spSvg" class="icon" width="16" height="16"></u-image> |
| | | <view class="name">{{approvalRecord.flightPlanName}}</view> |
| | | </view> |
| | | <view class="status">{{approvalRecord.planApprovalStatus || ''}}</view> |
| | | <view class="status" :class="getStatusClass(approvalRecord.planApprovalStatus)"> |
| | | {{ approvalRecord.planApprovalStatusLabel || ''}} |
| | | </view> |
| | | </view> |
| | | <view class="txt">飞行器:{{approvalRecord.device || ''}}</view> |
| | | <view class="txt">飞行任务:{{approvalRecord.flightTaskType || ''}}</view> |
| | | <view class="txt">飞行器:{{approvalRecord.spacecraftLabel || '无'}}</view> |
| | | <view class="txt">飞行任务:{{approvalRecord.flightTaskTypeLabel || ''}}</view> |
| | | <view class="txt">飞行起飞时间:{{approvalRecord.actualTakeoffTime || ''}}</view> |
| | | <view class="txt">飞行降落时间:{{approvalRecord.actualLandingTime || ''}}</view> |
| | | </view> |
| | |
| | | import { flightPlanPageInfoApi } from '@/api/index.js' |
| | | import fxsqSvg from '@/static/images/fly-apply.png' |
| | | import mysbSvg from '@/static/images/my-sb.png' |
| | | import { ref } from 'vue' |
| | | import { ref } from 'vue' |
| | | import { aircraftInfoPageInfoOfMyApi } from '@/api/index' |
| | | |
| | | // 获取store中的数据 字典 |
| | | import { useAppStore, useUserStore } from "@/store"; |
| | | const appStore = useAppStore() |
| | | |
| | | |
| | | function gridClick(index) { |
| | |
| | | } |
| | | } |
| | | |
| | | const getStatusClass = (status) => { |
| | | switch (status) { |
| | | case '0': |
| | | return 'Sorange' |
| | | case '99': |
| | | return 'Sgreen' |
| | | case '-1': |
| | | return 'Sred' |
| | | case '1': |
| | | return 'Sblue' |
| | | default: |
| | | return '' |
| | | } |
| | | } |
| | | |
| | | // 获取飞行器信息 |
| | | const aircraftInfoList = ref([]) |
| | | async function getAircraftInfo() { |
| | | try { |
| | | const res = await aircraftInfoPageInfoOfMyApi({ |
| | | current: 1, |
| | | size: 1000, |
| | | }) |
| | | aircraftInfoList.value = res.data.data.records.map(item => ({ |
| | | label: item.name, |
| | | value: item.id, |
| | | })) |
| | | } catch (error) { |
| | | console.error('获取飞行器信息失败:', error) |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // 审批记录是很多条 |
| | | const approvalRecords = ref([]) |
| | | const formParams = ref({ |
| | |
| | | try { |
| | | const res = await flightPlanPageInfoApi(formParams.value) |
| | | const newData = res.data.data.records || [] |
| | | // 处理字典数据 |
| | | newData.forEach(item => { |
| | | item.spacecraftLabel = aircraftInfoList.value.find(info => info.value === item.spacecraftId)?.label || '无' |
| | | item.planApprovalStatusLabel = appStore.flyActivityStatus.find(status => status.dictValue === item.planApprovalStatus)?.dictLabel || '无' |
| | | item.flightTaskTypeLabel = appStore.taskType.find(type => type.dictValue === item.flightTaskType)?.dictLabel || '无' |
| | | }) |
| | | // 如果是第一页,直接替换数据;否则追加数据 |
| | | if (formParams.value.current === 1) { |
| | | approvalRecords.value = newData |
| | |
| | | url: '/subPackages/flightApplication/details?id=' + item.id, |
| | | }) |
| | | } |
| | | onMounted(() => { |
| | | |
| | | |
| | | onMounted(async () => { |
| | | await getAircraftInfo() |
| | | getApprovalRecords() |
| | | }) |
| | | </script> |
| | |
| | | } |
| | | .name-status { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | // justify-content: space-between; |
| | | margin-bottom: 20rpx; |
| | | .name-image { |
| | | width: calc(100% - 120rpx); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | .u-image { |
| | | width: 32rpx; |
| | |
| | | font-size: 32rpx; |
| | | color: #1D2129; |
| | | margin-left: 6rpx; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | .status { |
| | | width: 100rpx; |
| | | text-align: center; |
| | | line-height: 40rpx; |
| | | background: #FF9604; |
| | | line-height: 44rpx; |
| | | height: 44rpx; |
| | | border-radius: 2px 2px 2px 2px; |
| | | font-weight: 500; |
| | | font-size: 24rpx; |
| | | color: #FFFFFF; |
| | | padding: 0 6rpx; |
| | | |
| | | &.Sorange { |
| | | background: #FF9604; |
| | | } |
| | | &.Sred { |
| | | background: #F8422A; |
| | | } |
| | | &.Sgreen { |
| | | background: #17A836; |
| | | } |
| | | &.Sblue { |
| | | background: #1D6FE9; |
| | | } |
| | | } |
| | | |
| | | } |
| | | .txt { |
| | | font-weight: 400; |
| | |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | <u-pdf-reader v-if="pdfUrl" :src="pdfUrl"></u-pdf-reader> |
| | | <!-- <u-pdf-reader v-if="pdfUrl" :src="pdfUrl"></u-pdf-reader> --> |
| | | </view> |
| | | </template> |
| | | <script setup> |
| | |
| | | td: 'border: 1px solid #ddd; padding: 8rpx;' |
| | | }; |
| | | |
| | | const pdfUrl = ref('') |
| | | const pdfUrl = ref('https://wrj.shuixiongit.com/minio/cloud-bucket/78611c83-8fb3-47c9-a18c-0349137bb30c/DJI_202601171733_001_78611c83-8fb3-47c9-a18c-0349137bb30c/DJI_20260117173534_0004_V.jpeg') |
| | | const fileObject = ref(null) |
| | | |
| | | function downloadFile(item) { |
| | | console.log(item,'999') |
| | | // aLinkDownloadUtil(item.fileUrl, item.fileName) |
| | | // downloadAndPreview(item.fileUrl, item.fileName) |
| | | pdfUrl.value = item.fileUrl |
| | | // downloadAndSavePDF(item.fileUrl, item.fileName) |
| | | } |
| | | // 下载并打开文件(支持PDF、图片、Word等) |
| | | const downloadAndPreview = async (fileUrl, fileName) => { |
| | | uni.showLoading({ |
| | | title: '下载中...', |
| | | mask: true |
| | | }) |
| | | |
| | | try { |
| | | // 1. 下载文件到临时目录 |
| | | const downloadRes = await uni.downloadFile({ |
| | | url: fileUrl, |
| | | timeout: 60000 |
| | | }) |
| | | |
| | | if (downloadRes.statusCode !== 200) { |
| | | throw new Error(`下载失败: ${downloadRes.statusCode}`) |
| | | } |
| | | |
| | | // 2. 打开文件(小程序会调用系统能力) |
| | | uni.openDocument({ |
| | | filePath: downloadRes.tempFilePath, |
| | | fileType: getFileType(fileName), |
| | | showMenu: true, // 显示右上角菜单 |
| | | success: () => { |
| | | console.log('打开文档成功') |
| | | uni.showToast({ |
| | | title: '已打开文件', |
| | | icon: 'success' |
| | | }) |
| | | }, |
| | | fail: (error) => { |
| | | console.error('打开失败:', error) |
| | | // 如果打开失败,尝试其他方式 |
| | | handleOpenFail(downloadRes.tempFilePath, fileName) |
| | | } |
| | | }) |
| | | |
| | | } catch (error) { |
| | | console.error('下载失败:', error) |
| | | uni.showToast({ |
| | | title: '下载失败,请重试', |
| | | icon: 'none' |
| | | }) |
| | | } finally { |
| | | uni.hideLoading() |
| | | } |
| | | console.log(item,'8888') |
| | | pdfUrl.value = item.filePreviewUrl |
| | | // fileObject.value = { |
| | | // url: item.fileUrl, |
| | | // name: item.fileName, |
| | | // extname: 'pdf' |
| | | // } |
| | | previewPdf(pdfUrl.value) |
| | | } |
| | | |
| | | // 下载并保存PDF到手机(iOS需要特殊处理) |
| | | const downloadAndSavePDF = (pdfUrl, fileName = 'document.pdf') => { |
| | | const previewPdf = (url) => { |
| | | uni.showLoading({ |
| | | title: '下载中...', |
| | | mask: true |
| | | title: '加载中...' |
| | | }) |
| | | |
| | | // 检查权限(主要针对iOS) |
| | | const checkAndDownload = () => { |
| | | uni.downloadFile({ |
| | | url: pdfUrl, |
| | | success: (downloadRes) => { |
| | | uni.hideLoading() |
| | | |
| | | if (downloadRes.statusCode === 200) { |
| | | const tempFilePath = downloadRes.tempFilePath |
| | | |
| | | // 保存到本地 |
| | | uni.saveFile({ |
| | | tempFilePath: tempFilePath, |
| | | success: (saveRes) => { |
| | | const savedFilePath = saveRes.savedFilePath |
| | | |
| | | uni.showModal({ |
| | | title: '下载成功', |
| | | content: `文件已保存到: ${savedFilePath}`, |
| | | showCancel: false, |
| | | success: () => { |
| | | // 可以引导用户去文件管理查看 |
| | | } |
| | | }) |
| | | }, |
| | | fail: (saveErr) => { |
| | | console.error('保存失败:', saveErr) |
| | | uni.showToast({ |
| | | title: '保存失败111', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | uni.hideLoading() |
| | | uni.showToast({ |
| | | title: '下载失败1111', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 检查文件访问权限 |
| | | uni.authorize({ |
| | | scope: 'scope.writePhotosAlbum', |
| | | success: () => { |
| | | checkAndDownload() |
| | | }, |
| | | fail: () => { |
| | | uni.showModal({ |
| | | title: '权限提示', |
| | | content: '需要文件存储权限才能下载文件', |
| | | success: (modalRes) => { |
| | | if (modalRes.confirm) { |
| | | uni.openSetting({ |
| | | success: (settingRes) => { |
| | | if (settingRes.authSetting['scope.writePhotosAlbum']) { |
| | | checkAndDownload() |
| | | } |
| | | } |
| | | // 1. 先下载文件到本地 |
| | | uni.downloadFile({ |
| | | url: url, |
| | | success: (res) => { |
| | | if (res.statusCode === 200) { |
| | | // 2. 打开文档 |
| | | uni.openDocument({ |
| | | filePath: res.tempFilePath, |
| | | fileType: 'pdf', |
| | | success: () => { |
| | | console.log('打开文档成功') |
| | | uni.hideLoading() |
| | | }, |
| | | fail: (err) => { |
| | | console.error('打开文档失败:', err) |
| | | uni.hideLoading() |
| | | uni.showToast({ |
| | | title: '打开文件失败', |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | console.error('下载文件失败:', err) |
| | | uni.hideLoading() |
| | | uni.showToast({ |
| | | title: '下载文件失败', |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | }) |
| | |
| | | const id = options.id || '1'; |
| | | regulationsDetailApi(id).then(res => { |
| | | htmlContent.value = res.data.data.noticeContent; |
| | | title.value = res.data.data.noticeTitle; |
| | | title.value = res.data.data.noticeDesc; |
| | | fileList.value = res.data.data.fileList || [] |
| | | }) |
| | | .catch(err => { |