123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- <template>
- <div class="hc-layout-box">
- <div class="hc-layout-left-box" :style="'width:' + leftWidth + 'px;'" v-if="dataType === 1">
- <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" v-loading="queryByLoading" element-loading-text="获取数据中...">
- <HcCard :title="`${treeItemInfo?.title ?? ''} 上传${fileType === 1 ? '视频' : fileType === 2 ? '图片' : ''}`" :scrollbar="false" actionSize="lg">
- <el-alert style="margin-bottom: 14px" title="请先在左边项目树,选择一个节点" type="warning" effect="dark" :closable="false" v-if="dataType === 1 && !wbsId"/>
- <el-row class="hc-form-row-box" :gutter="20">
- <el-col :span="10">
- <el-scrollbar>
- <el-form ref="formRef" :model="formValue" :rules="rules" label-width="auto" size="large">
- <el-form-item label="上传日期" prop="uploadTime">
- <el-date-picker v-model="formValue.uploadTime" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"/>
- </el-form-item>
- <el-form-item label="上传文件" prop="imageUrl">
- <div class="w-full">
- <HcUploads :fileList="uploadFileList" :accept="fileType === 1 ? videoAccept : fileType === 2 ? imageAccept : null" action="upload-file"
- :limit="fileType === 2 ? 10 : 1" :size="fileType === 2 ? 30 : 500" :viewer="false" @change="uploadsChange" @progress="uploadsProgress"
- @del="uploadsDel" @preview="uploadsPreview"/>
- </div>
- <el-image-viewer v-if="previewModal && fileType === 2" :initial-index="initialIndex" :url-list="previewFileList" @close="previewModalClose"/>
- <el-dialog v-model="previewVideoModal" width="62rem" destroy-on-close :before-close="previewModalClose">
- <video class="preview-video" :src="previewVideoUrl" controls="controls" autoplay="autoplay">
- 您的浏览器不支持 video
- </video>
- </el-dialog>
- <el-alert title="请上传MP4、MOV格式的视频文件,文件大小不超过500M,只能上传1个视频文件" type="error" :closable="false" v-if="fileType === 1"/>
- <el-alert title="请上传JPG/JPEG、PNG格式的图片文件,文件大小不超过30M,最多10张图片文件" type="error" :closable="false" v-if="fileType === 2"/>
- </el-form-item>
- <el-form-item label="题名" prop="title">
- <el-input v-model="formValue.title" placeholder="请输入题名"/>
- </el-form-item>
- <div class="flex">
- <el-form-item class="flex-1" :class="fileType === 2?'mr-4':''" prop="shootingUser" label="拍摄者">
- <el-input v-model="formValue.shootingUser" placeholder="请输入拍摄者"/>
- </el-form-item>
- <el-form-item class="flex-1 ml-4" label="照片号" v-if="fileType === 2">
- <el-input v-model="formValue.photoCode" placeholder="请输入照片号"/>
- </el-form-item>
- </div>
- <el-form-item label="拍摄时间" prop="shootingTimeStr">
- <el-date-picker v-model="formValue.shootingTimeStr" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"/>
- </el-form-item>
- <div class="flex" v-if="fileType === 2">
- <el-form-item class="flex-1 mr-4" prop="filmCode" label="底片号">
- <el-input v-model="formValue.filmCode" placeholder="请输入底片号"/>
- </el-form-item>
- <el-form-item class="flex-1 ml-4" prop="seeAlsoCode" label="参见号">
- <el-input v-model="formValue.seeAlsoCode" placeholder="请输入参见号"/>
- </el-form-item>
- </div>
- <el-form-item label="文字说明" prop="textContent">
- <el-input type="textarea" v-model="formValue.textContent" placeholder="请输入文字说明" :autosize="{ minRows: 3, maxRows: 5 }"/>
- </el-form-item>
- </el-form>
- </el-scrollbar>
- </el-col>
- <el-col :span="14">
- <HcTable :column="tableColumn" :datas="tableData" v-if="dataType === 2"/>
- </el-col>
- </el-row>
- <template #action>
- <el-button type="primary" :disabled="uploadsLoading || (dataType === 1 && !wbsId)" hc-btn :loading="saveLoading" @click="saveClick">
- <HcIcon name="save"/>
- <span>保存</span>
- </el-button>
- <el-button hc-btn :disabled="uploadsLoading" :loading="saveLoading" v-if="dataType === 2" @click="saveLogClick">
- <HcIcon name="save"/>
- <span>保存并再次添加</span>
- </el-button>
- <el-button hc-btn @click="toBackClick">
- <HcIcon name="arrow-go-back"/>
- <span>返回</span>
- </el-button>
- </template>
- </HcCard>
- </div>
- </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 imageApi from '~api/other-file/imageData';
- import {getStoreData, setStoreData} from '~src/utils/storage'
- import {formValidate, getObjValue, getRandom, deepClone, dateFormat} from "vue-utils-plus"
- import ossApi from "~api/oss";
- //变量
- 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 userInfo = ref(useAppState.getUserInfo)
- //路由参数
- const routerQuery = useRoutes?.query;
- //存储目录格式 1按部位存储,2按日期存储
- const dataId = routerQuery?.id || '';
- const wbsNodeIds = routerQuery?.wbsId || '';
- const classifyId = routerQuery?.classifyId || '';
- const dataType = parseInt(routerQuery?.dataType + '') || 1;
- const fileType = parseInt(routerQuery?.fileType + '') || 2;
- const toDayDate = dateFormat(new Date(), 'yyyy-MM-dd')
- const userRealName = ref('')
- //监听
- watch(() => [
- useAppState.getCollapse,
- useAppState.getUserInfo,
- useAppState.getContractId
- ], ([Collapse,UserInfo,ContractId]) => {
- isCollapse.value = Collapse
- userRealName.value = UserInfo['real_name']
- formValue.value.shootingUser = UserInfo['real_name']
- contractId.value=ContractId
- })
- watch(contractId, (val) => {
- if(val){
- router.push({
- path: '/other-file/image-data',
- })
- }
-
-
- })
- //自动展开缓存
- const TreeAutoExpandKeys = ref([])
- //渲染完成
- onMounted(() => {
- if (dataType === 1) {
- TreeAutoExpandKeys.value = getStoreData('TreeExpandKeys')
- }
- formDataFormat({})
- queryById()
- formValue.value.shootingUser = userInfo.value['real_name']
- })
- //详情
- const queryByLoading = ref(false)
- const queryById = async () => {
- if (dataId) {
- queryByLoading.value = true
- const {error, code, data} = await imageApi.queryById({id: dataId})
- //判断状态
- queryByLoading.value = false
- if (!error && code === 200) {
- formDataFormat(getObjValue(data))
- }
- }
- }
- //项目树被点击
- const wbsId = ref('')
- const treeItemInfo = ref({})
- const nodeWbsElTreeClick = ({data, keys}) => {
- if (data.leaf === true) {
- treeItemInfo.value = data
- wbsId.value = data['primaryKeyId']
- formValue.value.wbsId = data['primaryKeyId']
- //缓存自动展开
- TreeAutoExpandKeys.value = keys
- setStoreData('TreeExpandKeys', keys)
- } else {
- wbsId.value = ''
- treeItemInfo.value = {}
- formValue.value.wbsId = null
- }
- }
- //表单相关数据
- const formRef = ref(null)
- const formValue = ref({
- uploadTime: toDayDate,
- shootingTimeStr: toDayDate,
- shootingUser: '',
- filmCode: '',
- seeAlsoCode: '',
- })
- const rules = {
- uploadTime: {
- required: true,
- trigger: "blur",
- message: "请选择上传日期"
- },
- imageUrl: {
- required: true,
- message: "请先上传文件"
- },
- title: {
- required: true,
- trigger: "blur",
- message: "请输入题名"
- },
- shootingUser: {
- required: true,
- trigger: "blur",
- message: "请输入拍摄者"
- },
- shootingTimeStr: {
- required: true,
- trigger: "blur",
- message: "请选择拍摄时间"
- },
- }
- //表单默认数据
- const formDataFormat = (info) => {
- //表单数据
- formValue.value = {
- uploadTime: toDayDate,
- shootingTimeStr: toDayDate,
- ...info,
- type: fileType || '2',
- wbsId: info?.wbsId || wbsNodeIds,
- classifyId: info?.classifyId || classifyId,
- projectId: info?.projectId || projectId.value,
- contractId: info?.contractId || contractId.value,
- }
- //原始文件地址
- let imageUrl = info['imageUrl'] || '';
- let imageUrlArr = imageUrl ? imageUrl.split(',') : []
- //PDF地址
- let pdfUrl = info['pdfUrl'] || '';
- let pdfUrlArr = pdfUrl ? pdfUrl.split(',') : []
- //处理数据
- if (imageUrlArr.length > 0) {
- //状态处理
- let InfoPdfUrl = pdfUrlArr.length === imageUrlArr.length;
- //遍历数据
- for (let i = 0; i < imageUrlArr.length; i++) {
- let item = imageUrlArr[i];
- uploadFileList.value.push({
- name: getRandom(),
- url: item,
- page: '',
- pdfUrl: InfoPdfUrl ? pdfUrlArr[i] : ''
- })
- }
- } else {
- uploadFileList.value = []
- }
- }
- //上传组件参数
- const imageAccept = 'image/png,image/jpg,image/jpeg';
- const videoAccept = 'video/*';
- //上传文件的相关数据
- const previewFileList = ref([])
- const uploadFileList = ref([])
- //上传的文件结果
- const uploadsChange = ({ fileList}) => {
- uploadFileList.value = fileList
- }
- //上传进度
- const uploadsLoading = ref(false)
- const uploadsProgress = (val) => {
- uploadsLoading.value = val
- }
- //预览上传的文件
- const previewModal = ref(false)
- const previewVideoModal = ref(false)
- const initialIndex = ref(-1)
- const previewVideoUrl = ref('')
- const uploadsPreview = ({ index, fileArr}) => {
- if (fileType === 2) {
- previewFileList.value = fileArr
- initialIndex.value = index
- previewModal.value = true
- } else if (fileType === 1) {
- previewVideoUrl.value = fileArr[index]
- previewVideoModal.value = true
- }
- }
- //预览关闭
- const previewModalClose = () => {
- initialIndex.value = -1
- previewModal.value = false
- previewVideoModal.value = false
- }
- //删除上传的文件
- const uploadsDel = async ({link}) => {
- const arrUrl = link.split(".com//");
- if (arrUrl.length > 0) {
- await ossApi.removeFile({fileName: arrUrl[1]},false)
- }
- }
- //上传记录表格
- const tableColumn = ref([
- {name: '上传日期', key: 'uploadTime'},
- {name: '题名', key: 'title'},
- {name: '拍摄者', key: 'shootingUser'},
- {name: '拍摄时间', key: 'shootingTimeStr'}
- ])
- const tableData = ref([])
- //保存
- const saveLoading = ref(false)
- const saveClick = () => {
- verifyFormData(false)
- }
- //保存并添加记录
- const saveLogClick = () => {
- verifyFormData(true)
- }
- //表单效验
- const shootingTimeStr = ref('')
- const verifyFormData = async (log) => {
- const formData = formValue.value;
- const fileList = uploadFileList.value;
- //处理文件
- let imageUrl = '', pdfUrl = '';
- if (fileList.length > 0) {
- imageUrl = rowsToKey(fileList,'url')
- pdfUrl = rowsToKey(fileList,'pdfUrl')
- }
- //设置数据
- formData.imageUrl = imageUrl
- formData.pdfUrl = pdfUrl
- shootingTimeStr.value = formData['shootingTimeStr'] || ''
- //验证数据
- if (!formData?.wbsId && dataType === 1) {
- window.$message?.warning('请先选择节点')
- } else {
- const res = await formValidate(formRef.value)
- if (res) {
- if (formData?.id) {
- updateImageclassifyFile(formData,log)
- } else {
- addImageclassifyFile(formData,log)
- }
- } else {
- window.$message?.warning('请先完善表单')
- }
- }
- }
- //新增资料
- const addImageclassifyFile = async (formData,log) => {
- saveLoading.value = true
- const {error, code} = await imageApi.addImageclassifyFile(formData)
- //判断状态
- saveLoading.value = false
- if (!error && code === 200) {
- window.$message?.success('保存成功')
- if (log) {
- tableData.value.push(deepClone(formValue.value))
- formDataFormat({})
- } else {
- toBackClick()
- }
- }
- }
- //修改资料
- const updateImageclassifyFile = async (formData,log) => {
- saveLoading.value = true
- const {error, code} = await imageApi.updateImageclassifyFile(formData)
- //判断状态
- saveLoading.value = false
- if (!error && code === 200) {
- window.$message?.success('保存成功')
- if (log) {
- tableData.value.push(deepClone(formValue.value))
- formDataFormat({})
- } else {
- toBackClick()
- }
- }
- }
- //拼接字段
- const rowsToKey = (rows,key) => {
- return rows.map((obj) => {
- return obj[key];
- }).join(",")
- }
- //处理data类型的自动展开
- const dataNodeExpandKeys = () => {
- let TimeStr = shootingTimeStr.value || ''
- let TimeArr = TimeStr.split('-')
- if (TimeStr && TimeArr.length > 0) {
- let timeKey = TimeArr[0] + '-' + TimeArr[1];
- setStoreData('TreeExpandedKeys', [timeKey])
- }
- }
- //返回上页
- const toBackClick = () => {
- if (dataType === 1) {
- //NodeExpandKeys()
- } else if (dataType === 2) {
- dataNodeExpandKeys()
- }
- //返回上级
- router.push({
- path: '/other-file/image-view',
- query: {
- fileType: fileType,
- type: dataType,
- id: classifyId,
- }
- })
- setTimeout(()=>{
- window?.location?.reload() //刷新页面
- },1000)
- }
- //左右拖动,改变树形结构宽度
- const leftWidth = ref(382);
- const onmousedown = () => {
- const leftNum = isCollapse.value ? 142 : 272
- document.onmousemove = (ve) => {
- let 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/other-file/image-form.scss';
- </style>
- <style lang="scss">
- .hc-form-row-box {
- height: 100%;
- .el-col {
- height: 100%;
- .el-date-editor {
- --el-date-editor-width: 100%;
- .el-input__wrapper {
- width: 100%;
- }
- }
- .el-alert {
- margin-top: 14px;
- --el-alert-padding: 0px 16px;
- }
- }
- }
- .preview-video {
- width: 100%;
- }
- </style>
|