Merge branch 'master' of http://139.196.74.78:10010/r/jagzwxm/ja_web
| | |
| | | > |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="飞手姓名" prop="flyerName"> |
| | | <el-form-item label="飞手姓名" prop="flyerId"> |
| | | <el-select |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | v-model="formData.flyerName" |
| | | placeholder="请选择飞手姓名" |
| | | v-model="formData.flyerId" |
| | | placeholder="请选择" |
| | | clearable |
| | | @change="handleChange" |
| | | :disabled="dialogType === 'view'" |
| | | > |
| | | <el-option |
| | |
| | | <el-input |
| | | class="gd-input" |
| | | v-model="formData.flyerPhone" |
| | | placeholder="请输入飞手电话" |
| | | placeholder="请输入" |
| | | :disabled="dialogType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | |
| | | <el-input |
| | | class="gd-input" |
| | | v-model.number="formData.flightHours" |
| | | placeholder="请输入飞行时长" |
| | | placeholder="请输入" |
| | | type="number" |
| | | :disabled="dialogType === 'view'" |
| | | /> |
| | |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | v-model="formData.technicalStrength" |
| | | placeholder="请选择技术特长" |
| | | placeholder="请选择" |
| | | :disabled="dialogType === 'view'" |
| | | > |
| | | <el-option |
| | |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | v-model="formData.skilledUavType" |
| | | placeholder="请选择擅长机型" |
| | | placeholder="请选择" |
| | | :disabled="dialogType === 'view'" |
| | | clearable |
| | | @change="handleSearch" |
| | | > |
| | |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | v-model="formData.skilledTaskType" |
| | | placeholder="请选择擅长任务类型" |
| | | placeholder="请选择" |
| | | :disabled="dialogType === 'view'" |
| | | > |
| | | <el-option |
| | |
| | | <el-input |
| | | class="gd-input" |
| | | v-model="formData.projectExperience" |
| | | placeholder="请输入项目经验" |
| | | placeholder="请输入" |
| | | type="textarea" |
| | | rows="3" |
| | | :disabled="dialogType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24" v-if="dialogType === 'view'"> |
| | | <el-form-item label="飞手证书" prop="certification"> |
| | | <el-image |
| | | v-for="(item, index) in formData.certification" |
| | | :key="index" |
| | | :src="item" |
| | | :preview-src-list="formData.certification" |
| | | class="gd-image" |
| | | style="width: 100px; height: 100px; margin-right: 10px;" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | import { ref, reactive, computed, watch, inject } from 'vue' |
| | | import { submitFlyingHand } from './flyingHandApi' |
| | | import { ElMessage } from 'element-plus' |
| | | |
| | | import { fieldRules } from '@ztzf/utils' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | |
| | | const formRef = ref(null) |
| | | const formData = reactive({ |
| | | flyerName: '', |
| | | flyerId: '', |
| | | flyerPhone: '', |
| | | flightHours: 0, |
| | | projectExperience: '', |
| | | technicalStrength: '', |
| | | skilledUavType: '' |
| | | skilledUavType: '', |
| | | certification: [], // 证书 |
| | | }) |
| | | |
| | | const rules = { |
| | | flyerName: [ |
| | | { required: true, message: '请输入飞手姓名', trigger: 'blur' } |
| | | flyerId: [ |
| | | { required: true, message: '请输入', trigger: 'blur' } |
| | | ], |
| | | flyerPhone: [ |
| | | { required: false, message: '请输入飞手电话', trigger: 'blur' }, |
| | | { required: false, message: '请输入', trigger: 'blur' }, |
| | | { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' } |
| | | ], |
| | | flightHours: [ |
| | | { required: true, message: '请输入飞行时长', trigger: 'blur' }, |
| | | { required: true, message: '请输入', trigger: 'blur' }, |
| | | { type: 'number', min: 0, message: '飞行时长必须大于等于0', trigger: 'blur' } |
| | | ], |
| | | technicalSkills: [ |
| | | { required: true, message: '请选择技术特长', trigger: 'change' } |
| | | { required: true, message: '请选择', trigger: 'change' } |
| | | ], |
| | | skilledTaskType: [ |
| | | { required: true, message: '请选择擅长任务类型', trigger: 'change' } |
| | | { required: true, message: '请选择', trigger: 'change' } |
| | | ], |
| | | projectExperience: [ |
| | | { required: true, message: '请输入项目经验', trigger: 'blur' } |
| | | { required: true, message: '请输入', trigger: 'blur' } |
| | | ], |
| | | technicalStrength: [ |
| | | { required: true, message: '请选择技术特长', trigger: 'change' } |
| | | { required: true, message: '请选择', trigger: 'change' } |
| | | ], |
| | | skilledUavType: [ |
| | | { required: true, message: '请选择擅长机型', trigger: 'change' } |
| | | { required: true, message: '请选择', trigger: 'change' } |
| | | ] |
| | | } |
| | | |
| | |
| | | (newData) => { |
| | | if (newData) { |
| | | Object.assign(formData, newData) |
| | | formData.flightHours = Number(newData.flightHours) |
| | | } |
| | | }, |
| | | { deep: true, immediate: true } |
| | |
| | | resetForm() |
| | | } |
| | | |
| | | // 处理选择飞手姓名 |
| | | function handleChange(val) { |
| | | const result = flyingHandList.value.find(item => item.id === val) || [] |
| | | formData.flyerName = result.name |
| | | formData.certification = formData.certification.concat(result.licenseFrontFileUrl || [], result.licenseBackFileUrl || []) |
| | | } |
| | | |
| | | |
| | | |
| | | // 重置表单 |
| | | function resetForm() { |
| | | formRef.value?.resetFields() |
| | |
| | | // 飞手删除 |
| | | export function removeFlyingHand(data) { |
| | | return request({ |
| | | url: '/drone-gd/flyer/gdFlyer/remove', |
| | | url: `/drone-gd/flyer/gdFlyer/remove?ids=${data.ids}`, |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | |
| | | <basic-container> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form"> |
| | | <el-form-item label="飞手姓名" prop="flyerName"> |
| | | <el-input |
| | | class="gd-input gray" |
| | | v-model="searchParams.flyerName" |
| | | placeholder="请输入飞手姓名" |
| | | clearable |
| | | @clear="handleSearch" |
| | | /> |
| | | <el-select |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | v-model="searchParams.flyerName" |
| | | placeholder="请选择飞手姓名" |
| | | > |
| | | <el-option |
| | | v-for="item in flyingHandList" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="擅长机型" prop="skilledUavType"> |
| | |
| | | <template v-slot="{ row }"> |
| | | <el-link @click="viewFlyingHand(row)">查看</el-link> |
| | | <el-link type="primary" @click="editFlyingHand(row)">编辑</el-link> |
| | | <el-link type="danger" @click="deleteFlyingHand(row.id)">删除</el-link> |
| | | <el-link type="danger" @click="deleteFlyingHand(row)">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | import { getFlyingHandPage, removeFlyingHand } from './flyingHandApi' |
| | | import { deviceFlyerApi } from '@/api/zkxt' |
| | | import FlyingHandDialog from './FlyingHandDialog.vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { prod } from 'mathjs' |
| | | |
| | | // 初始化查询参数 |
| | |
| | | } |
| | | |
| | | // 删除飞手 |
| | | function deleteFlyingHand(id) { |
| | | ElMessageBox.confirm('确定要删除该飞手信息吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | async function deleteFlyingHand(row) { |
| | | const tips = row ? '该条' : '选中的项' |
| | | await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', { |
| | | type: 'warning', |
| | | }).then(async () => { |
| | | try { |
| | | await removeFlyingHand(id) |
| | | ElMessage.success('删除成功') |
| | | getList() |
| | | } catch (error) { |
| | | ElMessage.error('删除失败') |
| | | } |
| | | }).catch(() => { |
| | | // 取消删除 |
| | | customClass: 'gd-confirm-custom', |
| | | confirmButtonClass: 'gd-confirm-button', |
| | | cancelButtonClass: 'gd-confirm-cancel-button', |
| | | }) |
| | | const ids = row ? row.id : selectedIds.value.join(',') |
| | | await removeFlyingHand({ ids: ids }) |
| | | ElMessage.success('删除成功') |
| | | getList() |
| | | } |
| | | |
| | | // 处理弹窗确认 |
| | |
| | | <div class="label">数据来源依据</div> |
| | | <div class="val">{{ formData.dataSource }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-col :span="12"> |
| | | <div class="label">需求信息项</div> |
| | | <div class="val">{{ formData.demandInfo }}</div> |
| | | </el-col> |
| | |
| | | :model="formData" |
| | | :rules="rules" |
| | | :disabled="dialogReadonly" |
| | | label-width="160px" |
| | | label-width="190px" |
| | | > |
| | | <el-row> |
| | | <el-col :span="12"> |
| | |
| | | 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'] }], |
| | | }) |
| | | |
| | | // 获取字典 |
| | |
| | | :title="titleEnum[dialogMode]" |
| | | @closed="visible = false" |
| | | destroy-on-close |
| | | width="60%" |
| | | width="75%" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <div class="gd-dialog-form"> |
| | |
| | | <el-input class="gd-input" v-model="row.taskDesc" placeholder="请输入" :disabled="dialogReadonly" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="80" fixed="right" v-if="dialogMode === 'add'"> |
| | | <el-table-column label="操作" width="90" fixed="right" v-if="dialogMode === 'add'"> |
| | | <template v-slot="{ $index }"> |
| | | <el-button type="primary" :icon="Plus" circle size="small" @click="addTaskRow" /> |
| | | <el-button |
| | |
| | | :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-row> |
| | | <el-col span="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="营业收入" prop="operatingIncome"> |
| | | <el-input class="gd-input" v-model="editParams.operatingIncome" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col span="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="综合总成本费用" prop="totalCost"> |
| | | <el-input class="gd-input" v-model="editParams.totalCost" /> |
| | | </el-form-item> |
| | |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <el-col span="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="净利润" prop="netProfit"> |
| | | <el-input class="gd-input" v-model="editParams.netProfit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col span="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="财务内部收益率" prop="financialIrr"> |
| | | <el-input class="gd-input" v-model="editParams.financialIrr" /> |
| | | </el-form-item> |
| | |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <el-col span="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="市场空间" prop="marketSpace"> |
| | | <el-input class="gd-input" v-model="editParams.marketSpace" /> |
| | | </el-form-item> |
| | |
| | | <script setup> |
| | | import { ElMessage, ElMessageBox, ElLoading } from 'element-plus' |
| | | import { operatingIncomePage, operatingIncomeUpdate, operatingIncomeAdd, operatingIncomeBatchDelete } from './operatingIncomeApi' |
| | | |
| | | import { fieldRules } from '@ztzf/utils' |
| | | |
| | | let titleTxt = ref('新增') |
| | | const total = ref(0) |
| | |
| | | financialIrr: '', |
| | | marketSpace: '', |
| | | }) |
| | | |
| | | const rules = reactive({ |
| | | operatingIncome: [ |
| | | { required: true, message: '请输入营业收入', trigger: 'blur' }, |
| | | { required: true, message: '请输入', trigger: 'blur' }, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/^\d+(\.\d+)?$/.test(value)) { |
| | |
| | | } |
| | | ], |
| | | totalCost: [ |
| | | { required: true, message: '请输入综合总成本费用', trigger: 'blur' }, |
| | | { required: true, message: '请输入', trigger: 'blur' }, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/^\d+(\.\d+)?$/.test(value)) { |
| | |
| | | } |
| | | ], |
| | | netProfit: [ |
| | | { required: true, message: '请输入净利润', trigger: 'blur' }, |
| | | { required: true, message: '请输入', trigger: 'blur' }, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/^\d+(\.\d+)?$/.test(value)) { |
| | |
| | | } |
| | | ], |
| | | financialIrr: [ |
| | | { required: true, message: '请输入财务内部收益率', trigger: 'blur' }, |
| | | { required: true, message: '请输入', trigger: 'blur' }, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/^\d+(\.\d+)?$/.test(value)) { |
| | |
| | | } |
| | | ], |
| | | marketSpace: [ |
| | | { required: true, message: '请输入市场空间', trigger: 'blur' }, |
| | | { required: true, message: '请输入', trigger: 'blur' }, |
| | | ], |
| | | }) |
| | | |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="所属区划" prop="areaCode"> |
| | | <el-select |
| | | <el-tree-select |
| | | class="gd-select" |
| | | popper-class="gd-select-popper" |
| | | popper-class="gd-tree-select-popper" |
| | | v-model="formData.areaCode" |
| | | node-key="id" |
| | | :props="{ |
| | | value: 'id', |
| | | label: 'name', |
| | | children: 'children' |
| | | }" |
| | | placeholder="请选择" |
| | | clearable |
| | | > |
| | | <el-option v-for="item in regionOptions" :key="item.value" :label="item.title" :value="item.value" /> |
| | | </el-select> |
| | | filterable |
| | | :check-strictly="true" |
| | | lazy |
| | | :load="loadRegionNode" |
| | | :render-after-expand="false" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | import { |
| | | agenciesSubmitApi, |
| | | agenciesDetailApi, |
| | | regionLazyTreeApi |
| | | } from './agenciesApi' |
| | | |
| | | // 初始化表单数据 |
| | |
| | | await loadDetail() |
| | | } |
| | | } |
| | | |
| | | // 懒加载获取区域节点数据 |
| | | async function loadRegionNode(node, resolve) { |
| | | try { |
| | | const parentCode = node.data?.id || '360800000000' |
| | | const res = await regionLazyTreeApi({ parentCode }) |
| | | const nodes = res?.data?.data || [] |
| | | |
| | | // 处理返回的节点数据 |
| | | const processedNodes = nodes.map(item => { |
| | | return { |
| | | id: item.id || item.value, |
| | | name: item.name || item.title || item.label, |
| | | hasChildren: item.hasChildren || false |
| | | } |
| | | }) |
| | | |
| | | resolve(processedNodes) |
| | | } catch (error) { |
| | | console.error('获取区域数据失败:', error) |
| | | resolve([]) |
| | | } |
| | | } |
| | | // 获取初始区域数据(根节点) |
| | | async function getRegionList() { |
| | | try { |
| | | // 懒加载模式下,只需要初始化根节点 |
| | | const res = await regionLazyTreeApi({ parentCode: '360800000000' }) |
| | | const nodes = res?.data?.data || [] |
| | | |
| | | // 处理根节点数据 |
| | | regionOptions.value = nodes.map(item => { |
| | | return { |
| | | id: item.id || item.value, |
| | | name: item.name || item.title || item.label, |
| | | hasChildren: item.hasChildren || false |
| | | } |
| | | }) |
| | | } catch (error) { |
| | | console.error('获取区域数据失败:', error) |
| | | ElMessage.error('获取区域数据失败') |
| | | } |
| | | } |
| | | defineExpose({ open }) |
| | | |
| | | onMounted(() => { |
| | | getRegionList() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="机构编码" prop="bindCode"> |
| | | <el-form-item label="机构编码" prop="deptCode"> |
| | | <el-input |
| | | class="gd-input gray" |
| | | v-model="searchParams.bindCode" |
| | | v-model="searchParams.deptCode" |
| | | placeholder="请输入" |
| | | clearable |
| | | @clear="handleSearch" |
| | |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="所属区划" prop="areaCode"> |
| | | <el-select |
| | | <el-tree-select |
| | | class="gd-select gray" |
| | | popper-class="gd-select-popper" |
| | | popper-class="gd-tree-select-popper" |
| | | v-model="searchParams.areaCode" |
| | | node-key="id" |
| | | :props="treeSelectProps" |
| | | placeholder="请选择" |
| | | clearable |
| | | filterable |
| | | @change="handleSearch" |
| | | > |
| | | <el-option v-for="item in regionOptions" :key="item.value" :label="item.title" :value="item.value" /> |
| | | </el-select> |
| | | :check-strictly="true" |
| | | lazy |
| | | :load="loadRegionNode" |
| | | :render-after-expand="false" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item class="gd-search-actions"> |
| | |
| | | {{ ((searchParams.current - 1) * searchParams.size + $index + 1).toString().padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="bindCode" show-overflow-tooltip label="机构编码" /> |
| | | <el-table-column prop="deptCode" show-overflow-tooltip label="机构编码" /> |
| | | <el-table-column prop="deptName" show-overflow-tooltip label="机构名称" /> |
| | | <el-table-column prop="areaName" show-overflow-tooltip label="所属区划" /> |
| | | <el-table-column prop="remark" show-overflow-tooltip label="机构描述" /> |
| | |
| | | @close="handleImportClose" |
| | | > |
| | | <el-form class="gd-dialog-form" ref="importFormRef" :model="importParams" :rules="importRules" label-width="140px"> |
| | | |
| | | <el-form-item label="上传文件" prop="file"> |
| | | {{ importFileName }} |
| | | <el-upload class="avatar-uploader" action="" :show-file-list="false" :before-upload="onImportFileBefore"> |
| | |
| | | // 初始化查询参数 |
| | | const initSearchParams = () => ({ |
| | | deptName: '', // 机构名称 |
| | | bindCode: '', // 机构编码 |
| | | deptCode: '', // 机构编码 |
| | | areaCode: '', // 所属区划 |
| | | current: 1, // 当前页 |
| | | size: 10, // 每页大小 |
| | |
| | | const dialogVisible = ref(false) |
| | | const regionOptions = ref([]) // 区域选项 |
| | | const dictObj = ref({}) // 字典对象 |
| | | |
| | | // 树形选择器配置 |
| | | const treeSelectProps = { |
| | | value: 'id', |
| | | label: 'name', |
| | | children: 'children' |
| | | } |
| | | |
| | | |
| | | // 导入机构相关 |
| | | const isShowImportView = ref(false) |
| | |
| | | }) |
| | | } |
| | | |
| | | // 获取区域列表 |
| | | function getRegionList() { |
| | | regionLazyTreeApi({parentCode: '360800000000'}).then(res => { |
| | | console.log('区域列表', res.data.data); |
| | | |
| | | regionOptions.value = res.data.data || [] |
| | | }) |
| | | // 懒加载获取区域节点数据 |
| | | async function loadRegionNode(node, resolve) { |
| | | |
| | | try { |
| | | const parentCode = node.data?.id || '360800000000' |
| | | const res = await regionLazyTreeApi({ parentCode }) |
| | | const nodes = res?.data?.data || [] |
| | | |
| | | // 处理返回的节点数据 |
| | | const processedNodes = nodes.map(item => { |
| | | return { |
| | | id: item.id || item.value, |
| | | name: item.name || item.title || item.label, |
| | | hasChildren: item.hasChildren || false |
| | | } |
| | | }) |
| | | |
| | | resolve(processedNodes) |
| | | } catch (error) { |
| | | console.error('获取区域数据失败:', error) |
| | | resolve([]) |
| | | } |
| | | } |
| | | |
| | | // 获取初始区域数据(根节点) |
| | | async function getRegionList() { |
| | | try { |
| | | // 懒加载模式下,只需要初始化根节点 |
| | | const res = await regionLazyTreeApi({ parentCode: '360800000000' }) |
| | | const nodes = res?.data?.data || [] |
| | | |
| | | // 处理根节点数据 |
| | | regionOptions.value = nodes.map(item => { |
| | | return { |
| | | id: item.id || item.value, |
| | | name: item.name || item.title || item.label, |
| | | hasChildren: item.hasChildren || false |
| | | } |
| | | }) |
| | | } catch (error) { |
| | | console.error('获取区域数据失败:', error) |
| | | } |
| | | } |
| | | |
| | | // 获取列表 |
| | |
| | | |
| | | // 上传文件前处理 |
| | | function onImportFileBefore(file) { |
| | | // 执行文件上传 |
| | | // 检查文件类型 |
| | | const allowedTypes = ['.xlsx', '.xls'] |
| | | const fileExtension = file.name.substring(file.name.lastIndexOf('.')).toLowerCase() |
| | | if (!allowedTypes.includes(fileExtension)) { |
| | | ElMessage.error('请上传Excel文件(.xlsx 或 .xls)') |
| | | return false |
| | | } |
| | | let data = new FormData() |
| | | data.append('file', file) |
| | | |
| | |
| | | if (valid) { |
| | | importSubmitting.value = true |
| | | try { |
| | | // 这里实际上传文件的逻辑已经在onImportFileBefore中处理了 |
| | | // 这里可以添加额外的验证或逻辑 |
| | | if (!importParams.value.file) { |
| | | ElMessage.error('请先上传文件') |
| | | return |
| | | } |
| | | // 触发上传操作 |
| | | await onImportFileBefore(importParams.value.file) |
| | | } finally { |
| | | importSubmitting.value = false |
| | | } |