无人机管理后台前端(已迁走)
shuishen
2025-05-07 236f7535b87ec66316e4c09d8732cec3d865e0f0
Merge branch 'master' of http://139.196.74.78:10010/r/drone/drone-web-manage
1 files modified
177 ■■■■ changed files
src/views/tickets/ticket.vue 177 ●●●● patch | view | raw | blame | history
src/views/tickets/ticket.vue
@@ -327,7 +327,7 @@
            <el-col :span="12">
              <div class="media-box">
                <!-- 根据状态显示不同的标题和内容 -->
                <template v-if="currentDetail.status === 5">
                <template v-if="currentDetail.status === 4">
                  <div class="media-title">工单处理图片</div>
                  <div class="media-content">
                    <el-image v-if="currentDetail.updatePhotoUrl" :src="getThumbUrl(currentDetail.updatePhotoUrl)"
@@ -476,7 +476,7 @@
import { getAdcodeObj } from '@/utils/disposeData'
export default {
  name: "TicketPage",
  data () {
  data() {
    return {
      submitLoading: false, // 新增loading状态
      draftLoading: false,
@@ -557,16 +557,16 @@
          },
          { label: "创建人", prop: "creator", width: 100 },
          { label: "处理人", prop: "handler", width: 100 },
                   {
            label: "复核状态",
            prop: "isReview",
          {
            label: "复核状态",
            prop: "isReview",
            width: 90,
            formatter: (row) => {
              return row.isReview === 1 ? '是' : '否'
              return row.isReview === 1 ? '是' : '否'
            }
          },
          { label: "工单状态", prop: "status", slot: true, width: 90 },
        ],
      },
      page: {
@@ -652,7 +652,7 @@
      datePickerDefaultVal: calculateDefaultRange(),
    }
  },
  created () {
  created() {
    let orderNumber = new URLSearchParams(window.location.search).get('orderNumber')
    if (orderNumber) {
      this.filters.keyword = orderNumber
@@ -664,20 +664,20 @@
    console.log('permission.tickets_processing_btn', this.permission.tickets_processing_btn)
    console.log('permission', this.permission.tickets_tab_pending)
  },
  mounted () {
  mounted() {
    this.fetchTableData()
  },
  computed: {
    firstRowData () {
    firstRowData() {
      return this.tableData.length > 0 ? this.tableData[0] : null
    },
    availableHandlers () {
    availableHandlers() {
      return this.form.department ? (this.departmentUsers[this.form.department] || []) : []
    },
    availableDispatchHandlers () {
    availableDispatchHandlers() {
      return this.dispatchForm.department ? (this.departmentUsers[this.dispatchForm.department] || []) : []
    },
    detailTableData () {
    detailTableData() {
      return [
        {
          label: "工单名称",
@@ -735,7 +735,7 @@
        },
      ]
    },
    detailFields () {
    detailFields() {
      return [
        { label: "工单名称", value: this.currentDetail.orderName, editable: this.currentDetail.status === 0, type: "input" },
        { label: "关键任务", value: this.currentDetail.keyData, editable: false },
@@ -749,7 +749,7 @@
        { label: "工单内容", value: this.currentDetail.content, editable: this.currentDetail.status === 0, type: "textarea" },
      ]
    },
    formattedDetailFields () {
    formattedDetailFields() {
      const fields = [
        { label: "工单名称", value: this.currentDetail.orderName },
        { label: "工单类型", value: this.currentDetail.type },
@@ -775,13 +775,13 @@
      }
      return formattedFields
    },
    dynamicFixedStatuses () {
    dynamicFixedStatuses() {
      // 直接使用接口返回的 stepInfos
      return this.stepInfos.map(step => String(step.status))
    },
    ...mapGetters(['userInfo', 'permission']),
    // 动态过滤tabs,保证isShow为true/false
    filteredTabs () {
    filteredTabs() {
      // 统一处理权限,undefined视为false
      const tabStatus = this.permission?.tickets_tab_status === true
      const tabPending = this.permission?.tickets_tab_pending === true
@@ -802,7 +802,7 @@
        return { ...tab, isShow: false }
      }).filter(tab => tab.isShow)
    },
    permissionList () {
    permissionList() {
      // 可根据实际后端权限key调整
      return {
        addBtn: this.validData(this.permission.tickets_add, false),
@@ -811,7 +811,7 @@
        reviewBtn: this.validData(this.permission.tickets_review, false),
      }
    },
    stepStatusList () {
    stepStatusList() {
      // “我发起的工单”tab用默认流程,其它tab用接口返回的stepInfos
      if (this.activeTab === 'myTickets') {
        if (this.workType === 1) {
@@ -824,7 +824,7 @@
    },
  },
  methods: {
    async loadAMapScripts () {
    async loadAMapScripts() {
      try {
        const areaCode = this.userInfo.detail.areaCode
        const subAreaCode = areaCode ? areaCode.substring(0, 6) : ''
@@ -853,7 +853,7 @@
        this.$message.error('地图加载失败,请检查网络或API Key配置')
      }
    },
    async handleBatchApprove () {
    async handleBatchApprove() {
      try {
        if (this.selections.length === 0) {
          this.$message.warning('没有选中的工单')
@@ -911,7 +911,7 @@
        this.$message.error(error.message || '审核失败,请稍后重试')
      }
    },
    async fetchDropdownData () {
    async fetchDropdownData() {
      try {
        const response = await getTicketInfo()
        const { dept_data, event_type, ai_type } = response.data.data
@@ -952,7 +952,7 @@
      }
    },
    async fetchTableData () {
    async fetchTableData() {
      if (this.isFetching) return
      this.isFetching = true
      this.loading = true
@@ -1043,7 +1043,7 @@
      }
    },
    async submitForm () {
    async submitForm() {
      if (this.submitLoading) return // 防止重复提交
      this.submitLoading = true
      try {
@@ -1117,7 +1117,7 @@
      }
    },
    async saveDraft () {
    async saveDraft() {
      if (this.draftLoading) return // 防止重复提交
      this.draftLoading = true
      try {
@@ -1177,7 +1177,7 @@
      }
    },
    handleLocationChange (val) {
    handleLocationChange(val) {
      let locationValue = val.value
      console.log('handleLocationChange', locationValue)
      if (locationValue && locationValue.length >= 2) {
@@ -1194,13 +1194,13 @@
      }
    },
    formatDate (date) {
    formatDate(date) {
      if (!date) return undefined
      const d = new Date(date)
      return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} 00:00:00`
    },
    mapStatus (status) {
    mapStatus(status) {
      const statusTextMap = {
        "-1": "草稿",  // 添加草稿状态
        "2": "待审核",
@@ -1212,7 +1212,7 @@
      return statusTextMap[status] || "未知状态"
    },
    getStatusTagType (status) {
    getStatusTagType(status) {
      // 草稿不加颜色
      if (status === -1 || status === "-1") return ''
      // 状态颜色映射
@@ -1226,7 +1226,7 @@
      return colorMap[String(status)] || ''
    },
    async fetchTabCounts () {
    async fetchTabCounts() {
      try {
        // 判断是否有部门筛选
        let params = {}
@@ -1249,7 +1249,7 @@
      }
    },
    handleTabChange (tab) {
    handleTabChange(tab) {
      this.activeTab = tab.props?.name || tab.name
      this.handleReset()
      this.page.currentPage = 1
@@ -1257,13 +1257,13 @@
      this.fetchTabCounts() // 切换 tab 时重新获取数据
    },
    handleSearch () {
    handleSearch() {
      this.page.currentPage = 1
      this.fetchTableData()
      this.fetchTabCounts()
    },
    handleReset () {
    handleReset() {
      this.filters = {
        keyword: "",
        department: "",
@@ -1277,7 +1277,7 @@
      this.fetchTableData()
    },
    async handleCurrentChange (val) {
    async handleCurrentChange(val) {
      // 先更新页码
      this.page.currentPage = val
      // 等待 DOM 更新后再请求数据
@@ -1285,18 +1285,18 @@
      await this.fetchTableData()
    },
    async sizeChange (val) {
    async sizeChange(val) {
      this.page.pageSize = val
      this.page.currentPage = 1 // 重置到第一页
      await this.$nextTick()
      await this.fetchTableData()
    },
    handleAdd () {
    handleAdd() {
      this.dialogVisible = true
    },
    resetForm () {
    resetForm() {
      this.form = {
        name: '',
        type: '',
@@ -1314,14 +1314,14 @@
      }
    },
    formatLocation (location) {
    formatLocation(location) {
      if (!Array.isArray(location)) {
        return '未知位置'
      }
      return `${location[0].toFixed(6)}, ${location[1].toFixed(6)}`
    },
    async handleViewDetail (row) {
    async handleViewDetail(row) {
      // 先设置workType,直接从row读取
      this.workType = row.work_type !== undefined ? Number(row.work_type) : 0
@@ -1392,53 +1392,53 @@
      })
    },
    getStepHandler (status) {
    getStepHandler(status) {
      const step = this.stepInfos.find(step => step.status === status)
      return step ? step.name : ''
    },
    getStepTime (status) {
    getStepTime(status) {
      const step = this.stepInfos.find(step => step.status === status)
      // 如果 step 不存在或 step.time 为 0,返回 false
      return step && step.time && step.time !== '0' ? step.time : false
    },
    getStepCreateTime (status) {
    getStepCreateTime(status) {
      const step = this.stepInfos.find(step => step.status === status)
      return step ? step.create_time : null
    },
    getActiveStep () {
    getActiveStep() {
      // 步骤索引适配
      const arr = this.stepStatusList
      const index = arr.indexOf(String(this.currentDetail.status))
      return index !== -1 ? index + 2 : 1
    },
    openMap () {
    openMap() {
      const areaCode = this.userInfo.detail.areaCode
      const subAreaCode = areaCode ? areaCode.substring(0, 6) : ''
      getAdcodeObj(geoJson, 'adcode', subAreaCode)
      this.$message.info("地图选址功能暂未实现")
    },
    handlePreview (file) {
    handlePreview(file) {
      this.$message.info(`预览图片:${file.name}`)
    },
    handleRemove (file) {
    handleRemove(file) {
      this.$message.info(`移除图片:${file.name}`)
    },
    refreshChange () {
    refreshChange() {
      if (this.isFetching) return
      this.fetchTableData()
    },
    onLoad () {
    onLoad() {
      if (this.isFetching) return
      this.fetchTableData()
    },
    async exportData () {
    async exportData() {
      // 修改导出方法,添加选中数据的处理
      try {
        this.loading = true
@@ -1539,16 +1539,16 @@
      }
    },
    handleDepartmentChange (deptId) {
    handleDepartmentChange(deptId) {
      this.form.handler = ''
    },
    handleDispatchDepartmentChange (deptId) {
    handleDispatchDepartmentChange(deptId) {
      this.dispatchForm.handler = '' // 清空处理人选择
    },
    // 文件改变时的钩子
    handleFileChange (file, fileList) {
    handleFileChange(file, fileList) {
      // 保持最新的文件列表
      this.form.photos = fileList.map(item => ({
        ...item,
@@ -1558,13 +1558,13 @@
    },
    // 文件移除时的钩子
    handleUploadRemove (file, fileList) {
    handleUploadRemove(file, fileList) {
      this.form.photos = fileList
      this.currentDetail.photos = fileList
    },
    // 上传前的验证
    beforeUpload (file) {
    beforeUpload(file) {
      const isImage = file.type.includes('image')
      const isLt5M = file.size / 1024 / 1024 < 5
@@ -1579,7 +1579,7 @@
      return true
    },
    async approveTicket () {
    async approveTicket() {
      if (this.approveLoading) return
      this.approveLoading = true
      try {
@@ -1606,7 +1606,7 @@
        this.approveLoading = false
      }
    },
    async rejectTicket () {
    async rejectTicket() {
      if (this.rejectLoading) return
      this.rejectLoading = true
      try {
@@ -1630,7 +1630,7 @@
        this.rejectLoading = false
      }
    },
    async submitProcessing () {
    async submitProcessing() {
      if (this.currentDetail.status !== 3) {
        this.$message.warning('只有处理中状态的工单可以提交处理详情')
        return
@@ -1660,10 +1660,10 @@
        this.$message.error(error.message || '提交失败,请稍后重试')
      }
    },
    markAsCompleted () {
    markAsCompleted() {
      this.$message.success("工单已标记为完成")
    },
    async completeTicket () {
    async completeTicket() {
      if (this.completeLoading) return
      this.completeLoading = true
      try {
@@ -1671,6 +1671,13 @@
          this.$message.warning('请先填写事件处理详情')
          return
        }
        // 检查图片上传
        if (!this.currentDetail.photos || this.currentDetail.photos.length === 0) {
          this.$message.warning('请选择上传图片')
          this.completeLoading = false
          return
        }
        const data = {
          id: this.currentDetail.id,
@@ -1698,7 +1705,7 @@
        this.completeLoading = false
      }
    },
    async approveAndDispatch () {
    async approveAndDispatch() {
      if (this.dispatchLoading) return
      // 添加必填项检查
@@ -1718,22 +1725,22 @@
      // 通过验证后,打开派发对话框
      this.dispatchDialogVisible = true
    },
    hasProcessingBtnPermission () {
    hasProcessingBtnPermission() {
      // undefined 或 false 都返回 false,只有 true 返回 true
      console.log('权限检查:', this.permission)
      return this.permission && this.permission.tickets_processing_btn === true
    },
    hasProcessedAndOverBtnPermission () {
    hasProcessedAndOverBtnPermission() {
      // undefined 或 false 都返回 false,只有 true 返回 true
      console.log('权限检查:', this.permission)
      return this.permission && this.permission.tickets_view_processedAndOver === true
    },
    hasReviewBtnPermission () {
    hasReviewBtnPermission() {
      // undefined 或 false 都返回 false,只有 true 返回 true
      console.log('权限检查:', this.permission)
      return this.permission && this.permission.tickets_review_btn === true
    },
    async submitDispatch () {
    async submitDispatch() {
      if (this.dispatchLoading) return
      if (!this.currentDetail.orderName || !this.currentDetail.orderName.trim()) {
        this.$message.warning('请填写工单名称')
@@ -1794,7 +1801,7 @@
        }
      })
    },
    async finalizeTicket () {
    async finalizeTicket() {
      if (this.finalizeLoading) return
      this.finalizeLoading = true
      try {
@@ -1830,7 +1837,7 @@
    },
    // 添加编辑方法
    handleEdit (row) {
    handleEdit(row) {
      console.log('编辑原始数据:', row)
      // 尝试从row.dept_id或通过部门名称查找对应的部门ID
@@ -1947,7 +1954,7 @@
    },
    // 添加删除方法
    handleDelete (row) {
    handleDelete(row) {
      this.$confirm('确认删除该工单?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
@@ -1974,23 +1981,23 @@
    },
    // 添加选择变化处理方法
    handleSelectionChange (selection) {
    handleSelectionChange(selection) {
      this.selections = selection
      console.log('已选择的行:', selection)
    },
    // 添加全选方法
    handleSelectAll (val) {
    handleSelectAll(val) {
      this.$refs.avueCrud.toggleSelection(val)
    },
    // 添加单行选择方法
    handleSelect (selection, row) {
    handleSelect(selection, row) {
      console.log('选中行变化:', selection, row)
    },
    // 如果需要手动选中某些行
    setSelection (rows) {
    setSelection(rows) {
      this.$nextTick(() => {
        rows.forEach(row => {
          this.$refs.avueCrud.toggleSelection(row, true)
@@ -1999,12 +2006,12 @@
    },
    // 清空选择
    clearSelection () {
    clearSelection() {
      this.$refs.avueCrud.clearSelection()
    },
    // 打开审核对话框
    openReviewDialog () {
    openReviewDialog() {
      if (this.selections.length === 0) {
        this.$message.warning('请先选择要审核的工单')
        return
@@ -2015,7 +2022,7 @@
    },
    // 更新当前审核图片
    updateCurrentReviewImage () {
    updateCurrentReviewImage() {
      // 修正索引范围
      if (!this.selections || this.selections.length === 0) {
        this.currentReviewImage = ''
@@ -2039,7 +2046,7 @@
    },
    // 处理图片分页变化
    handleImagePageChange (page) {
    handleImagePageChange(page) {
      if (page > 0 && page <= this.selections.length) {
        this.currentImageIndex = page
        this.updateCurrentReviewImage()
@@ -2047,7 +2054,7 @@
    },
    // 批量审核通过
    async handleBatchApprove () {
    async handleBatchApprove() {
      try {
        if (this.selections.length === 0) {
          this.$message.warning('没有选中的工单')
@@ -2107,7 +2114,7 @@
      }
    },
    cancleBatchReject () {
    cancleBatchReject() {
      this.reviewDialogVisible = false
      this.selections = []
      this.currentImageIndex = 1
@@ -2115,7 +2122,7 @@
      this.fetchTableData()
    },
    // 批量审核不通过
    async handleBatchReject () {
    async handleBatchReject() {
      try {
        if (this.selections.length === 0) {
          this.$message.warning('没有选中的工单')
@@ -2176,19 +2183,19 @@
    },
    // 获取所有图片列表用于预览
    getImageList () {
    getImageList() {
      return this.selections
        .map(item => this.getPreviewUrl(item.photo_url))
        .filter(url => url) // 过滤掉空值
    },
    // 处理图片点击
    handleImageClick () {
    handleImageClick() {
      // 图片点击事件由 el-image 的预览功能处理
    },
    // 处理上一张图片
    handlePrevImage () {
    handlePrevImage() {
      if (this.currentImageIndex > 1) {
        this.currentImageIndex--
        this.updateCurrentReviewImage()
@@ -2196,7 +2203,7 @@
    },
    // 处理下一张图片
    handleNextImage () {
    handleNextImage() {
      if (this.currentImageIndex < this.selections.length) {
        this.currentImageIndex++
        this.updateCurrentReviewImage()
@@ -2208,7 +2215,7 @@
     * @param {string} url 原图地址
     * @returns {string} 缩略图地址
     */
    getThumbUrl (url) {
    getThumbUrl(url) {
      if (!url) return ''
      const lastDot = url.lastIndexOf('.')
      if (lastDot === -1) return url
@@ -2216,7 +2223,7 @@
    },
    // 添加新方法:获取预览图地址
    getPreviewUrl (url) {
    getPreviewUrl(url) {
      if (!url) return ''
      const lastDot = url.lastIndexOf('.')
      if (lastDot === -1) return url
@@ -2227,7 +2234,7 @@
     * 坐标转换方法处理
     * @param goWgs84 是否由国测转换到84,默认false----由84转换到国测
     */
    disposeLocation (goWgs84 = false, data) {
    disposeLocation(goWgs84 = false, data) {
      let lng, lat
      if (goWgs84) {
        lng = data.location?.[0] ? String(data.location[0]) : undefined