123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- <template>
- <div class="hc-layout-box">
- <div v-if="dataType === 1" :style="`width:${leftWidth}px;`" class="hc-layout-left-box">
- <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
- :auto-expand-keys="TreeAutoExpandKeys" :contract-id="contractId" :project-id="projectId" :class-id="dataId"
- @nodeTap="nodeWbsElTreeClick"
- />
- </el-scrollbar>
- </div>
- <!-- 左右拖动 -->
- <div class="horizontal-drag-line" @mousedown="onmousedown" />
- </div>
- <div v-loading="queryByLoading" class="hc-layout-content-box" element-loading-text="获取数据中...">
- <HcCard
- :scrollbar="false"
- :title="`${treeItemInfo?.title ?? ''} 上传${fileType === 1 ? '视频' : fileType === 2 ? '图片' : ''}`"
- action-size="lg"
- >
- <el-alert
- v-if="dataType === 1 && !wbsId" :closable="false" effect="dark" style="margin-bottom: 14px"
- title="请先在左边项目树,选择一个节点" type="warning"
- />
- <el-row :gutter="20" class="hc-form-row-box">
- <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" format="YYYY-MM-DD" type="date"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- <el-form-item label="上传文件" prop="imageUrl">
- <div class="w-full">
- <HcUploads
- :accept="fileType === 1 ? videoAccept : fileType === 2 ? imageAccept : null"
- :file-list="uploadFileList"
- :limit="fileType === 2 ? 10 : 1"
- :size="fileType === 2 ? 30 : 500" :viewer="false"
- action="upload-file" @change="uploadsChange" @del="uploadsDel"
- @preview="uploadsPreview" @progress="uploadsProgress"
- />
- </div>
- <el-image-viewer
- v-if="previewModal && fileType === 2" :initial-index="initialIndex"
- :url-list="previewFileList" @close="previewModalClose"
- />
- <el-dialog
- v-model="previewVideoModal" :before-close="previewModalClose"
- destroy-on-close
- width="62rem"
- >
- <video
- :src="previewVideoUrl" autoplay="autoplay" class="preview-video"
- controls="controls"
- >
- 您的浏览器不支持 video
- </video>
- </el-dialog>
- <el-alert
- v-if="fileType === 1"
- :closable="false"
- title="请上传MP4、MOV格式的视频文件,文件大小不超过500M,只能上传1个视频文件"
- type="error"
- />
- <el-alert
- v-if="fileType === 2"
- :closable="false"
- title="请上传JPG/JPEG、PNG格式的图片文件,文件大小不超过30M,最多10张图片文件"
- type="error"
- />
- </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="fileType === 2 ? 'mr-4' : ''" class="flex-1" label="拍摄者"
- prop="shootingUser"
- >
- <el-input v-model="formValue.shootingUser" placeholder="请输入拍摄者" />
- </el-form-item>
- <el-form-item v-if="fileType === 2" class="flex-1 ml-4" label="照片号">
- <el-input v-model="formValue.photoCode" placeholder="请输入照片号" />
- </el-form-item>
- </div>
- <el-form-item label="拍摄时间" prop="shootingTimeStr">
- <el-date-picker
- v-model="formValue.shootingTimeStr" format="YYYY-MM-DD" type="date"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- <div v-if="fileType === 2" class="flex">
- <el-form-item class="flex-1 mr-4" label="底片号" prop="filmCode">
- <el-input v-model="formValue.filmCode" placeholder="请输入底片号" />
- </el-form-item>
- <el-form-item class="flex-1 ml-4" label="参见号" prop="seeAlsoCode">
- <el-input v-model="formValue.seeAlsoCode" placeholder="请输入参见号" />
- </el-form-item>
- </div>
- <el-form-item label="文字说明" prop="textContent">
- <el-input
- v-model="formValue.textContent" :autosize="{ minRows: 3, maxRows: 5 }"
- placeholder="请输入文字说明" type="textarea"
- />
- </el-form-item>
- </el-form>
- </el-scrollbar>
- </el-col>
- <el-col :span="14">
- <HcTable v-if="dataType === 2" :column="tableColumn" :datas="tableData" />
- </el-col>
- </el-row>
- <template #action>
- <el-button
- :disabled="uploadsLoading || (dataType === 1 && !wbsId)" :loading="saveLoading" hc-btn
- type="primary" @click="saveClick"
- >
- <HcIcon name="save" />
- <span>保存</span>
- </el-button>
- <el-button
- v-if="dataType === 2" :disabled="uploadsLoading" :loading="saveLoading" hc-btn
- @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 { useRoute, useRouter } from 'vue-router'
- import WbsTree from './components/WbsTree.vue'
- import imageApi from '~api/other-file/imageData'
- import { getStoreValue, setStoreValue } from '~src/utils/storage'
- import { arrToKey, deepClone, formValidate, getObjValue, getRandom } from 'js-fast-way'
- import { dateFormat } from '~src/utils/tools'
- 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 = getStoreValue('TreeExpandKeys')
- }
- formDataFormat({})
- queryById()
- formValue.value.shootingUser = userInfo.value['real_name']
- if (wbsNodeIds) {
- getFileTitleNamedata(wbsNodeIds)
- }
- })
- //详情
- 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 getFileTitleNamedata = async (wbsNodeIds) => {
- const { error, code, data } = await imageApi.getFileTitleName({ pKeyId: wbsNodeIds })
- //判断状态
- if (!error && code === 200) {
- let arr = Object.keys(data)
- if (arr.length > 0) {
- formValue.value.title = data
- } else {
- formValue.value.title = ''
- }
- }
- }
- //项目树被点击
- 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']
- getFileTitleNamedata(data['primaryKeyId'])
- //缓存自动展开
- TreeAutoExpandKeys.value = keys
- setStoreValue('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 = arrToKey(fileList, 'url', ',')
- pdfUrl = arrToKey(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()
- }
- }
- }
- //处理data类型的自动展开
- const dataNodeExpandKeys = () => {
- let TimeStr = shootingTimeStr.value || ''
- let TimeArr = TimeStr.split('-')
- if (TimeStr && TimeArr.length > 0) {
- let timeKey = TimeArr[0] + '-' + TimeArr[1]
- setStoreValue('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>
|