123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682 |
- <template>
- <div class="hc-layout-box">
- <div class="hc-layout-left-box" :style="'width:' + leftWidth + 'px;'" v-if="sbTableKey !== 'weather'">
- <div class="hc-project-box">
- <div class="hc-project-icon-box">
- <HcIcon name="stack"/>
- </div>
- <div class="ml-2 project-name-box">
- <span class="text-xl text-cut project-alias">{{projectInfo['projectAlias']}}</span>
- <div class="text-xs text-cut project-name">{{projectInfo['name']}}</div>
- </div>
- </div>
- <div class="hc-tree-box">
- <el-scrollbar>
- <WbsTree :autoExpandKeys="treeAutoExpandKeys" :projectId="projectId" :contractId="contractId" @nodeTap="nodeWbsElTreeClick"/>
- </el-scrollbar>
- </div>
- <!--左右拖动-->
- <div class="horizontal-drag-line" @mousedown="onmousedown"/>
- </div>
- <div class="hc-layout-content-box">
- <HcTabsSimple :datas="sbTableData" :cur="sbTableKey" @tabClick="sbTableClick">
- <template #tab-internal>
- <HcCard v-if="sbTableKey === 'internal'">
- <template #header>
- <div class="w-32">
- <el-select v-model="searchInternalForm.taskStatus" placeholder="审批状态" clearable size="large">
- <el-option v-for="item in InternalApproval" :key="item.value" :label="item['label']" :value="item['value']"/>
- </el-select>
- </div>
- <div class="w-32 ml-2">
- <el-select v-model="searchInternalForm.isEvaluate" placeholder="是否评定" clearable size="large">
- <el-option v-for="item in InternalAssess" :key="item.value" :label="item['label']" :value="item['value']"/>
- </el-select>
- </div>
- <div class="w-32 ml-2">
- <el-select v-model="searchInternalForm.reportNumber" placeholder="上报批次" clearable size="large">
- <el-option v-for="item in InternalReportBatch" :key="item.value" :label="item['label']" :value="item['value']"/>
- </el-select>
- </div>
- <div class="w-32 ml-2">
- <el-select v-model="searchInternalForm.isExperiment" placeholder="关联试验" clearable size="large">
- <el-option v-for="item in InternalAssociation" :key="item.value" :label="item['label']" :value="item['value']"/>
- </el-select>
- </div>
- <div class="w-60 ml-2">
- <el-input v-model="searchInternalForm.queryStr" placeholder="请输入名称关键词检索" size="large" clearable @keyup="searchInternalKeyUp"/>
- </div>
- <div class="ml-2">
- <el-button type="primary" size="large" @click="searchInternalClick">
- <HcIcon name="search-2"/>
- <span>搜索</span>
- </el-button>
- </div>
- </template>
- <template #extra>
- <HcTooltip keys="write_industry_download">
- <el-button type="primary" hc-btn :disabled="tableInternalKeys.length <= 0">
- <HcIcon name="download"/>
- <span>下载</span>
- </el-button>
- </HcTooltip>
- <HcTooltip keys="write_industry_print">
- <el-button hc-btn :disabled="tableInternalKeys.length <= 0">
- <HcIcon name="printer"/>
- <span>打印</span>
- </el-button>
- </HcTooltip>
- </template>
- <HcTable ref="tableInternalRef" :column="tableInternalColumn" :datas="tableInternalData" :loading="tableInternalLoading" isCheck @selection-change="tableInternalSelection">
- <template #taskStatus="{row}">
- <el-tag type="success" class="mx-1" effect="dark" v-if="row['taskStatus'] === '已审批'">已审批</el-tag>
- <el-tag type="danger" class="mx-1" effect="dark" v-if="row['taskStatus'] === '待审批'">待审批</el-tag>
- <el-tag type="warning" class="mx-1" effect="dark" v-if="row['taskStatus'] === '未上报'">未上报</el-tag>
- </template>
- <template #isEvaluate="{row}">
- <el-tag type="success" class="mx-1" effect="dark" v-if="row['isEvaluate']">是</el-tag>
- <el-tag type="info" class="mx-1" effect="dark" v-else>否</el-tag>
- </template>
- <template #isExperiment="{row}">
- <el-tag type="success" class="mx-1" effect="dark" v-if="row['isExperiment']">是</el-tag>
- <el-tag type="info" class="mx-1" effect="dark" v-else>否</el-tag>
- </template>
- </HcTable>
- <template #action>
- <HcPages :pages="searchInternalForm" @change="pageInternalChange"/>
- </template>
- </HcCard>
- </template>
- <template #tab-construction>
- <HcCard v-if="sbTableKey === 'construction'">
- <HcTable :column="tableConstructionColumn" :datas="tableConstructionData" :loading="tableConstructionLoading">
- <template #action="{row}">
- <HcTooltip keys="write_construction_edit">
- <el-button type="primary" plain size="small" @click="tableConstructionEdit(row)">
- <HcIcon name="edit"/>
- <span>编辑</span>
- </el-button>
- </HcTooltip>
- </template>
- </HcTable>
- <template #action>
- <HcPages :pages="searchConstructionForm" @change="pageConstructionChange"/>
- </template>
- </HcCard>
- </template>
- <template #tab-weather>
- <HcCard v-if="sbTableKey === 'weather'">
- <template #header>
- <div class="w-64">
- <HcDatePicker :dates="weatherTime" size="large" clearable @change="weatherTimeUpdate"/>
- </div>
- <div class="ml-2">
- <el-button type="primary" size="large" @click="searchWeatherClick">搜索</el-button>
- </div>
- </template>
- <template #extra>
- <HcTooltip keys="write_weather_print">
- <el-button hc-btn>
- <HcIcon name="printer"/>
- <span>打印</span>
- </el-button>
- </HcTooltip>
- </template>
- <HcTable :column="tableWeatherColumn" :datas="tableWeatherData" :loading="tableWeatherLoading">
- <template #tempLow="{row}">{{row['tempLow']}} ~ {{row['tempHigh']}}</template>
- <template #action="{row}">
- <HcTooltip keys="write_weather_edit">
- <el-button type="primary" plain size="small" @click="tableWeatherEdit(row)">
- <HcIcon name="edit"/>
- <span>编辑</span>
- </el-button>
- </HcTooltip>
- </template>
- </HcTable>
- <template #action>
- <HcPages :pages="searchWeatherForm" @change="pageWeatherChange"/>
- </template>
- </HcCard>
- </template>
- </HcTabsSimple>
- </div>
- <!--编辑施工台账-->
- <el-dialog v-model="showConstructionEditModal" title="编辑施工台账" width="38rem" class="hc-modal-border">
- <el-form ref="constructionFormRef" :model="constructionFormModel" :rules="constructionFormRules" label-width="auto" size="large">
- el-form-item
- </el-form>
- <!--n-form ref="formRef" :model="formValue" :rules="rules" label-placement="left" label-width="auto" size="large">
- <n-form-item label="施工起止日期" path="siteTimeStr">
- <n-date-picker class="flex-1" v-model:formatted-value="siteTime" value-format="yyyy-MM-dd" type="daterange" clearable @update:value="siteTimeUpdate"/>
- </n-form-item>
- <n-form-item label="检测起止日期" path="detectionTimeStr">
- <n-date-picker class="flex-1" v-model:formatted-value="detectionTime" value-format="yyyy-MM-dd" type="daterange" clearable @update:value="detectionTimeUpdate"/>
- </n-form-item>
- <div class="flex">
- <n-form-item class="flex-1" label="设计方量">
- <n-input v-model:value="formValue.designVolume" placeholder="请输入设计方量"/>
- </n-form-item>
- <n-form-item class="flex-1" label="实际方量">
- <n-input v-model:value="formValue.actualVolume" placeholder="请输入实际方量"/>
- </n-form-item>
- </div>
- </n-form-->
- <template #footer>
- <div class="dialog-footer">
- <el-button size="large" @click="showConstructionEditModal = false">
- <HcIcon name="close"/>
- <span>取消</span>
- </el-button>
- <el-button type="primary" hc-btn :loading="saveConstructionLoading" @click="saveConstructionClick">
- <HcIcon name="save"/>
- <span>提交保存</span>
- </el-button>
- </div>
- </template>
- </el-dialog>
- <!--编辑天气台账-->
- <el-dialog v-model="showWeatherEditModal" title="编辑天气台账" width="38rem" class="hc-modal-border">
- <el-form ref="weatherFormRef" :model="weatherFormModel" :rules="weatherFormRules" label-width="auto" size="large">
- <el-form-item label="日期">
- <el-input v-model="weatherFormModel.recordTime" disabled/>
- </el-form-item>
- <el-form-item label="天气" prop="weather">
- <el-input v-model="weatherFormModel.weather" placeholder="天气"/>
- </el-form-item>
- <el-form-item label="最低温度" prop="tempLow">
- <el-input type="number" v-model="weatherFormModel.tempLow" placeholder="最低温度"/>
- </el-form-item>
- <el-form-item label="最高温度" prop="tempHigh">
- <el-input type="number" v-model="weatherFormModel.tempHigh" placeholder="最高温度"/>
- </el-form-item>
- <el-form-item label="风力" prop="windLevel">
- <el-input v-model="weatherFormModel.windLevel" placeholder="风力"/>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button size="large" @click="showWeatherEditModal = false">
- <HcIcon name="close"/>
- <span>取消</span>
- </el-button>
- <el-button type="primary" hc-btn :loading="saveWeatherLoading" @click="saveWeatherClick">
- <HcIcon name="save"/>
- <span>提交保存</span>
- </el-button>
- </div>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup>
- import {onMounted, ref, watch} from 'vue'
- import {useAppStore} from "~src/store";
- import {useRouter, useRoute} from 'vue-router'
- import WbsTree from "./components/WbsTree.vue"
- import weatherApi from '~api/ledger/weather';
- import internalApi from '~api/ledger/internal';
- import constructionApi from '~api/ledger/construction';
- import {getStoreData, setStoreData} from '~src/utils/storage'
- import {getArrValue, deepClone, formValidate} from "vue-utils-plus"
- //变量
- const router = useRouter()
- const useRoutes = useRoute()
- const useAppState = useAppStore()
- const projectId = ref(useAppState.getProjectId);
- const contractId = ref(useAppState.getContractId);
- const projectInfo = ref(useAppState.getProjectInfo);
- const isCollapse = ref(useAppState.getCollapse)
- //路由参数
- const routerQuery = useRoutes?.query;
- const dataType = routerQuery?.type || 'weather';
- //监听
- watch(() => [
- useAppState.getCollapse
- ], ([Collapse]) => {
- isCollapse.value = Collapse
- })
- //自动展开缓存
- const treeAutoExpandKeys = ref([])
- //类型处理
- const sbTableKey = ref(dataType)
- const sbTableData = ref([
- {icon: 'bar-chart-box', label: '内业台账', key: 'internal'},
- {icon: 'tools', label: '施工台账', key: 'construction'},
- {icon: 'sun-cloudy', label: '天气台账', key: 'weather'},
- ])
- const sbTableClick = (key) => {
- sbTableKey.value = key
- router.push({
- path: useRoutes.path,
- query: {type: key}
- })
- getTypeData(key)
- }
- //加载完成
- onMounted(() => {
- getTypeData(dataType)
- })
- //根据类型获取相关数据
- const getTypeData = (key) => {
- if (key === 'weather') {
- searchWeatherClick()
- } else if (key === 'internal' || key === 'construction') {
- treeAutoExpandKeys.value = getStoreData('ledgerWriteTreeKeys') || []
- setWbsIds()
- }
- }
- //树被点击
- const nodeDataInfo = ref({})
- const nodeWbsElTreeClick = ({data, keys}) => {
- nodeDataInfo.value = data
- //缓存节点
- setStoreData('ledgerWriteTreeKeys',keys)
- treeAutoExpandKeys.value = keys || []
- setWbsIds()
- }
- const setWbsIds = () => {
- const key = sbTableKey.value
- const data = nodeDataInfo.value
- const cid = data?.contractIdRelation || ''
- const wbsId = data['contractIdRelation'] ? data['id'] : data['primaryKeyId']
- if (wbsId && key === 'internal') {
- searchInternalForm.value.contractId = cid ? cid : contractId.value;
- searchInternalForm.value.contractIdRelation = data['contractIdRelation']
- searchInternalForm.value.wbsIds = [wbsId]
- searchInternalClick()
- } else if (wbsId && key === 'construction') {
- searchConstructionForm.value.contractId = cid ? cid : contractId.value;
- searchConstructionForm.value.contractIdRelation = data['contractIdRelation']
- searchConstructionForm.value.wbsIds = [wbsId]
- searchConstructionClick()
- }
- }
- //--------内业台账---------
- //审批状态
- const InternalApproval = ref([
- {label: "未上报", value: "1"},
- {label: "待审批", value: "2"},
- {label: "已审批", value: "3"}
- ])
- //是否评定
- const InternalAssess = ref([
- {label: "是", value: true},
- {label: "否", value: false}
- ])
- //上报批次
- const InternalReportBatch = ref([])
- //是否关联试验
- const InternalAssociation = ref([
- {label: "是", value: true},
- {label: "否", value: false}
- ])
- //搜索表单
- const searchInternalForm = ref({
- taskStatus: null, isEvaluate: null, reportNumber: null, isExperiment: null,
- current: 1, size: 20, total: 0
- })
- //回车
- const searchInternalKeyUp = (e) => {
- if (e.key === "Enter") {
- searchInternalClick()
- }
- }
- //搜索
- const searchInternalClick = () => {
- if (searchInternalForm.value?.wbsIds) {
- searchInternalForm.value.current = 1;
- getTableInternalData()
- } else {
- window?.$message?.warning('请先选择一个树节点')
- }
- }
- //分页被点击
- const pageInternalChange = ({current, size}) => {
- searchInternalForm.value.current = current
- searchInternalForm.value.size = size
- getTableInternalData()
- }
- //内业台账表头
- const tableInternalRef = ref(null)
- const tableInternalColumn = ref([
- {key:'unitProject', name: '单位工程'},
- {key:'partProject', name: '分部工程'},
- {key:'partChildProject', name: '子分部工程'},
- {key:'subentryProject', name: '分项工程'},
- {key:'subentryChildProject', name: '子分项工程'},
- {key:'process', name: '工序'},
- {key:'taskStatus', name: '审批状态', width: 120, align: 'center'},
- {key:'reportNumber', name: '上报批次', width: 100, align: 'center'},
- {key:'isEvaluate', name: '是否评定', width: 100, align: 'center'},
- {key:'isExperiment', name: '关联试验', width: 100, align: 'center'},
- ])
- const tableInternalData = ref([])
- //获取数据
- const tableInternalLoading = ref(false)
- const getTableInternalData = async () => {
- tableInternalLoading.value = true
- const {error, code, data} = await internalApi.queryInternalPage({
- ...searchInternalForm.value,
- projectId: projectId.value,
- })
- //判断状态
- tableInternalLoading.value = false
- if (!error && code === 200) {
- tableInternalData.value = getArrValue(data['records'])
- searchInternalForm.value.total = data['total'] || 0
- } else {
- tableInternalData.value = []
- searchInternalForm.value.total = 0
- }
- }
- //多选
- const tableInternalKeys = ref([]);
- const tableInternalSelection = (rows) => {
- tableInternalKeys.value = rows.filter((item) => {
- return (item??'') !== '';
- })
- }
- //--------内业台账 end---------
- //--------施工台账---------
- //搜索表单
- const searchConstructionForm = ref({current: 1, size: 20, total: 0})
- //搜索
- const searchConstructionClick = () => {
- if (searchConstructionForm.value?.wbsIds) {
- searchConstructionForm.value.current = 1;
- getTableConstructionData()
- } else {
- window?.$message?.warning('请先选择一个树节点')
- }
- }
- //分页被点击
- const pageConstructionChange = ({current, size}) => {
- searchConstructionForm.value.current = current
- searchConstructionForm.value.size = size
- getTableConstructionData()
- }
- //施工台账表头
- const tableConstructionColumn = ref([
- {key:'station', name: '施工桩号'},
- {key:'site', name: '施工部位'},
- {key:'siteTimeStr', name: '施工起止日期'},
- {key:'detectionTimeStr', name: '检测日期'},
- {key:'designVolume', name: '设计方量'},
- {key:'actualVolume', name: '实际方量'},
- {key:'action', name: '操作', width: 100}
- ])
- const tableConstructionData = ref([])
- //获取数据
- const tableConstructionLoading = ref(false)
- const getTableConstructionData = async () => {
- tableConstructionLoading.value = true
- const {error, code, data} = await constructionApi.queryConstructionPage({
- ...searchConstructionForm.value,
- projectId: projectId.value,
- })
- //判断状态
- tableConstructionLoading.value = false
- if (!error && code === 200) {
- tableConstructionData.value = getArrValue(data['records'])
- searchConstructionForm.value.total = data['total'] || 0
- } else {
- tableConstructionData.value = []
- searchConstructionForm.value.total = 0
- }
- }
- //施工台账编辑
- const showConstructionEditModal = ref(false)
- const tableConstructionEdit = (row) => {
- showConstructionEditModal.value = true
- }
- //施工台账表单
- const constructionFormRef = ref(null)
- const constructionFormModel = ref({
- recordTime: '',
- weather: '',
- tempLow: null,
- tempHigh: null,
- windLevel: ''
- })
- const constructionFormRules = ref({
- weather: {
- required: true,
- trigger: 'blur',
- message: "请输入天气"
- },
- tempLow: {
- required: true,
- validator: (rule, value, callback) => {
- const tempHigh = weatherFormModel.value?.tempHigh ?? ''
- const val = Number(value)
- const high = Number(tempHigh);
- if (!val) {
- callback(new Error('请输入最低温度'))
- } else if (val > high) {
- callback(new Error('最低温度不能高于最高温度'))
- } else if (val === high) {
- callback(new Error('最低温度和最高温度,不能一致'))
- } else {
- callback()
- }
- },
- trigger: "blur",
- },
- })
- //提交保存
- const saveConstructionLoading = ref(false)
- const saveConstructionClick = async () => {
- const validate = await formValidate(constructionFormRef.value)
- if (validate) {
- console.log(validate)
- //updateConstructionPage
- }
- }
- //--------施工台账 end---------
- //--------天气台账---------
- //搜索表单
- const searchWeatherForm = ref({recordTime: '', current: 1, size: 20, total: 0})
- //日期时间被选择
- const weatherTime = ref(null)
- const weatherTimeUpdate = ({val,arr}) => {
- weatherTime.value = arr
- searchWeatherForm.value.recordTime = val['start'] + '~' + val['end']
- }
- //搜索
- const searchWeatherClick = () => {
- searchWeatherForm.value.current = 1;
- getTableWeatherData()
- }
- //分页被点击
- const pageWeatherChange = ({current, size}) => {
- searchWeatherForm.value.current = current
- searchWeatherForm.value.size = size
- getTableWeatherData()
- }
- //天气台账表头
- const tableWeatherColumn = ref([
- {key:'recordTime', name: '日期'},
- {key:'weather', name: '天气'},
- {key:'tempLow', name: '温度 ℃'},
- {key:'airTemp', name: '平均温度 ℃'},
- {key:'windLevel', name: '风力'},
- {key:'action', name: '操作', width: 100}
- ])
- const tableWeatherData = ref([])
- //获取数据
- const tableWeatherLoading = ref(false)
- const getTableWeatherData = async () => {
- tableWeatherLoading.value = true
- const {error, code, data} = await weatherApi.queryWeatherPage({
- ...searchWeatherForm.value,
- projectId: projectId.value,
- contractId: contractId.value
- })
- //判断状态
- tableWeatherLoading.value = false
- if (!error && code === 200) {
- tableWeatherData.value = getArrValue(data['records'])
- searchWeatherForm.value.total = data['total'] || 0
- } else {
- tableWeatherData.value = []
- searchWeatherForm.value.total = 0
- }
- }
- //天气台账编辑
- const showWeatherEditModal = ref(false)
- const tableWeatherEdit = (row) => {
- weatherFormModel.value = deepClone(row)
- saveWeatherLoading.value = false
- showWeatherEditModal.value = true
- }
- //天气台账表单
- const weatherFormRef = ref(null)
- const weatherFormModel = ref({recordTime: '', weather: '', tempLow: null, tempHigh: null, windLevel: ''})
- const weatherFormRules = ref({
- weather: {
- required: true,
- trigger: 'blur',
- message: "请输入天气"
- },
- tempLow: {
- required: true,
- validator: (rule, value, callback) => {
- const tempHigh = weatherFormModel.value?.tempHigh ?? ''
- const val = Number(value)
- const high = Number(tempHigh);
- if (!val) {
- callback(new Error('请输入最低温度'))
- } else if (val > high) {
- callback(new Error('最低温度不能高于最高温度'))
- } else if (val === high) {
- callback(new Error('最低温度和最高温度,不能一致'))
- } else {
- callback()
- }
- },
- trigger: "blur",
- },
- tempHigh: {
- required: true,
- validator: (rule, value, callback) => {
- const tempLow = weatherFormModel.value?.tempLow ?? ''
- const val = Number(value)
- const low = Number(tempLow);
- if (!val) {
- callback(new Error('请输入最高温度'))
- } else if (val < low) {
- callback(new Error('最高温度不能低于最低温度'))
- } else if (val === low) {
- callback(new Error('最高温度和最低温度,不能一致'))
- } else {
- callback()
- }
- },
- trigger: "blur",
- },
- windLevel: {
- required: true,
- trigger: 'blur',
- message: "请输入风力"
- },
- })
- //提交保存
- const saveWeatherLoading = ref(false)
- const saveWeatherClick = async () => {
- const validate = await formValidate(weatherFormRef.value)
- if (validate) {
- //发起请求
- saveWeatherLoading.value = true
- const {error, code} = await weatherApi.updateWeatherById({
- ...weatherFormModel.value,
- projectId: projectId.value,
- contractId: contractId.value
- },false)
- //处理数据
- saveWeatherLoading.value = false
- if (!error && code === 200) {
- window?.$message?.success('保存成功')
- showWeatherEditModal.value = false;
- getTableWeatherData()
- } else {
- window?.$message?.error('保存失败')
- }
- }
- }
- //--------天气台账 end---------
- //左右拖动,改变树形结构宽度
- const leftWidth = ref(382);
- const onmousedown = () => {
- const leftNum = isCollapse.value ? 142 : 272
- document.onmousemove = (ve) => {
- const diffVal = ve.clientX - leftNum;
- if(diffVal >= 310 && diffVal <= 900) {
- leftWidth.value = diffVal;
- }
- }
- document.onmouseup = () => {
- document.onmousemove = null;
- document.onmouseup = null;
- }
- }
- </script>
- <style lang="scss" scoped>
- @import "../../styles/ledger/write.scss";
- </style>
- <style lang="scss">
- .hc-layout-box .hc-layout-content-box .hc-card-box.el-card {
- border-radius: 0 var(--el-card-border-radius) var(--el-card-border-radius) var(--el-card-border-radius);
- height: calc(100% - 44px);
- }
- </style>
|