From e0661837a51388897afe05281168c43879dcefcd Mon Sep 17 00:00:00 2001
From: rain <1679827795@qq.com>
Date: Thu, 10 Apr 2025 11:06:11 +0800
Subject: [PATCH] 工单列表

---
 /dev/null                    |   86 ---
 src/views/tickets/ticket.vue | 1224 ++++++++++++++++++++++++++++++++++++--------------
 src/api/tickets/ticket.js    |   28 +
 index.html                   |   73 +-
 4 files changed, 945 insertions(+), 466 deletions(-)

diff --git a/index.html b/index.html
index 3e93af7..6de0d9e 100644
--- a/index.html
+++ b/index.html
@@ -1,32 +1,40 @@
 <!DOCTYPE html>
 <html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
-    <meta http-equiv="X-UA-Compatible" content="chrome=1" />
-    <meta name="renderer" content="webkit" />
-    <meta
-      name="viewport"
-      content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"
-    />
-    <meta name="apple-mobile-web-app-capable" content="yes" />
-    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
-    <meta name="format-detection" content="telephone=no" />
-    <link rel="icon" href="/favicon.png" />
-    <link rel="stylesheet" href="/iconfont/index.css" />
-    <link rel="stylesheet" href="/iconfont/avue/iconfont.css" />
-    <link rel="stylesheet" href="/iconfont/saber/iconfont.css" />
-    <link rel="stylesheet" href="/css/loading.css" />
-    <link rel="stylesheet" href="/css/saber.css" />
-    <!-- <script src="https://unpkg.com/axios/dist/axios.min.js"></script> -->
-    <title>中图智绘低空无人机监测网平台</title>
-  </head>
 
-  <body class="theme-white">
-    <div id="app">
-      <div id="loader-wrapper">
-        <!-- <div class='loader-box'>
+<head>
+  <meta charset="UTF-8" />
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+  <meta http-equiv="X-UA-Compatible" content="chrome=1" />
+  <meta name="renderer" content="webkit" />
+  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
+  <meta name="apple-mobile-web-app-capable" content="yes" />
+  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+  <meta name="format-detection" content="telephone=no" />
+  <link rel="icon" href="/favicon.png" />
+  <link rel="stylesheet" href="/iconfont/index.css" />
+  <link rel="stylesheet" href="/iconfont/avue/iconfont.css" />
+  <link rel="stylesheet" href="/iconfont/saber/iconfont.css" />
+  <link rel="stylesheet" href="/css/loading.css" />
+  <link rel="stylesheet" href="/css/saber.css" />
+  <!-- <script src="https://unpkg.com/axios/dist/axios.min.js"></script> -->
+  <!-- 导入需要的包 (一定要放到index.html中的head标签里) -->
+  <!-- 高德地图api更新必须配合安全密钥使用 -->
+  <script>
+    window._AMapSecurityConfig = {
+      securityJsCode: '4fb5f6dbb164e46890e2cde357024bbc',
+    }
+  </script>
+  <script type="text/javascript"
+    src='https://webapi.amap.com/maps?v=2.0&key=4b49ed77772d77e9a8c36f6a4663eaa9&plugin=AMap.PlaceSearch,AMap.Geocoder'></script>
+  <script src="https://webapi.amap.com/ui/1.1/main.js?v=1.0.11"></script>
+  <title>中图智绘低空无人机监测网平台</title>
+</head>
+
+<body class="theme-white">
+  <div id="app">
+    <div id="loader-wrapper">
+      <!-- <div class='loader-box'>
       <span>无</span>
       <span>人</span>
       <span>机</span>
@@ -37,13 +45,13 @@
       <span>系</span>
       <span>统</span>
     </div> -->
-        <div class="loader-title">系统加载中</div>
-      </div>
+      <div class="loader-title">系统加载中</div>
     </div>
-    <script type="module" src="/src/main.js"></script>
-  </body>
+  </div>
+  <script type="module" src="/src/main.js"></script>
+</body>
 
-  <!-- <script>
+<!-- <script>
     document.addEventListener('DOMContentLoaded', function () {
       var getData = function (name) {
         var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
@@ -63,4 +71,5 @@
       });
     });
   </script> -->
-</html>
+
+</html>
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
deleted file mode 100644
index d998b08..0000000
--- a/public/index.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<script type="text/javascript">
-  window._AMapSecurityConfig = {
-    securityJsCode: '', // 替换为高德平台生成的安全密钥
-  };
-</script>
-<script src="https://webapi.amap.com/maps?v=1.4.11&key=7873666321486813e3eedad751bb9608&plugin=AMap.PlaceSearch,AMap.Geocoder"></script>
-<script src="https://webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
diff --git a/src/api/tickets/ticket.js b/src/api/tickets/ticket.js
index 124d7d2..3aae420 100644
--- a/src/api/tickets/ticket.js
+++ b/src/api/tickets/ticket.js
@@ -8,11 +8,33 @@
   });
 };
 
-export const createTicket = (data) => {
+// 修改创建工单的方法
+export const createTicket = (data, file) => {
+  const formData = new FormData();
+  
+  // 添加文件到 eventDto 中作为一个字段
+  const eventDto = {
+    ...data,
+    file: null // 后端会处理这个字段
+  };
+
+  // 添加所有字段到 FormData
+  Object.entries(eventDto).forEach(([key, value]) => {
+    formData.append(key, value);
+  });
+  
+  // 单独添加文件
+  if (file) {
+    formData.append("file", file);
+  }
+
   return request({
-    url: '/drone-device-core/jobEvent/eventPage',
+    url: '/drone-device-core/jobEvent/saveEvent',
     method: 'post',
-    data,
+    data: formData,
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    }
   });
 };
 
diff --git a/src/utils/map-config.js b/src/utils/map-config.js
deleted file mode 100644
index 56103a0..0000000
--- a/src/utils/map-config.js
+++ /dev/null
@@ -1,86 +0,0 @@
-window._AMapSecurityConfig = {
-  securityJsCode: '', // 替换为高德平台生成的安全密钥
-};
-
-export const loadAMap = () => {
-  return new Promise((resolve, reject) => {
-    if (window.AMap) {
-      resolve(window.AMap);
-      return;
-    }
-
-    const script = document.createElement('script');
-    script.src = `https://webapi.amap.com/maps?v=1.4.11&key=7873666321486813e3eedad751bb9608&plugin=AMap.PlaceSearch,AMap.Geocoder`; // 替换为你的 API Key
-    script.onerror = () => reject(new Error('Failed to load AMap script'));
-    script.onload = () => {
-      if (window.AMap) {
-        resolve(window.AMap);
-      } else {
-        reject(new Error('AMap failed to initialize'));
-      }
-    };
-
-    document.body.appendChild(script);
-  });
-};
-
-export const loadAMapUI = () => {
-  return new Promise((resolve, reject) => {
-    if (window.AMapUI) {
-      resolve(window.AMapUI);
-      return;
-    }
-
-    const script = document.createElement('script');
-    script.src = 'https://webapi.amap.com/ui/1.0/main.js?v=1.0.11';
-    script.onerror = () => reject(new Error('Failed to load AMap UI script'));
-    script.onload = () => {
-      if (window.AMapUI) {
-        resolve(window.AMapUI);
-      } else {
-        reject(new Error('AMap UI failed to initialize'));
-      }
-    };
-
-    document.body.appendChild(script);
-  });
-};
-
-export const initPoiPicker = () => {
-  return new Promise((resolve, reject) => {
-    loadAMap()
-      .then(() => loadAMapUI())
-      .then((AMapUI) => {
-        AMapUI.loadUI(['misc/PoiPicker'], (PoiPicker) => {
-          if (!PoiPicker) {
-            reject(new Error('PoiPicker failed to load'));
-            return;
-          }
-          const poiPicker = new PoiPicker();
-          resolve(poiPicker);
-        });
-      })
-      .catch((error) => {
-        console.error('Error initializing PoiPicker:', error);
-        reject(error);
-      });
-  });
-};
-
-export const initGeocoder = () => {
-  return new Promise((resolve, reject) => {
-    loadAMap()
-      .then((AMap) => {
-        try {
-          const geocoder = new AMap.Geocoder();
-          resolve(geocoder);
-        } catch (error) {
-          reject(new Error('Failed to initialize Geocoder'));
-        }
-      })
-      .catch((error) => {
-        console.error('Error initializing Geocoder:', error);
-        reject(error);
-      });
-  });
-};
diff --git a/src/views/tickets/ticket.vue b/src/views/tickets/ticket.vue
index f21c5a0..6d3eb7d 100644
--- a/src/views/tickets/ticket.vue
+++ b/src/views/tickets/ticket.vue
@@ -5,103 +5,43 @@
         <div class="tab-content">
           <!-- 查询条件筛选栏 -->
           <div class="filter-bar">
-            <el-input
-              v-model="filters.keyword"
-              placeholder="请输入关键字"
-              class="filter-item"
-              clearable
-              @keyup.enter="handleSearch"
-            />
-            <el-select
-              v-model="filters.department"
-              placeholder="请选择所属单位"
-              class="filter-item"
-              clearable
-            >
-              <el-option
-                v-for="item in departments"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
-              />
+            <el-input v-model="filters.keyword" placeholder="请输入关键字" class="filter-item" clearable
+              @keyup.enter="handleSearch" />
+            <el-select v-model="filters.department" placeholder="请选择所属单位" class="filter-item" clearable>
+              <el-option v-for="item in departments" :key="item.value" :label="item.label" :value="item.value" />
             </el-select>
-            <el-select
-              v-model="filters.type"
-              placeholder="请选择工单类型"
-              class="filter-item"
-              clearable
-            >
-              <el-option
-                v-for="item in types"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
-              />
+            <el-select v-model="filters.type" placeholder="请选择工单类型" class="filter-item" clearable>
+              <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" />
             </el-select>
-            <el-date-picker
-              v-model="filters.dateRange"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-              class="date-picker"
-              value-format="yyyy-MM-dd"
-            />
-            <el-select
-              v-model="filters.status"
-              placeholder="请选择状态"
-              class="filter-item"
-              clearable
-            >
-              <el-option
-                v-for="item in statuses"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
-              />
+            <el-date-picker v-model="filters.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
+              end-placeholder="结束日期" class="date-picker" value-format="yyyy-MM-dd" />
+            <el-select v-model="filters.status" placeholder="请选择状态" class="filter-item" clearable>
+              <el-option v-for="item in statuses" :key="item.value" :label="item.label" :value="item.value" />
             </el-select>
             <el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button>
             <el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
           </div>
 
           <!-- 表格部分 -->
-          <avue-crud
-            :data="tableData"
-            :option="option"
-            :page.sync="pagination"
-            :table-loading="loading"
-            @current-change="handlePaginationChange"
-            @size-change="handlePaginationChange"
-            @refresh-change="refreshChange"
-            @on-load="onLoad"
-          >
+          <avue-crud :data="tableData" :option="option" :page="{
+            total: page.total,
+            currentPage: page.currentPage,
+            pageSize: page.pageSize,
+            pageSizes: [10000, 20000, 30000]
+          }" @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange"
+            @on-load="onLoad" :table-loading="loading">
             <template #menu-left>
-              <el-button 
-                type="primary" 
-                icon="el-icon-plus" 
-                @click="handleAdd"
-              >新建工单</el-button>
-              <el-button 
-                type="success" 
-                plain 
-                icon="el-icon-download" 
-                @click="exportData"
-              >导出</el-button>
+              <!-- <el-button type="primary" icon="el-icon-plus" @click="handleAdd">新建工单</el-button> -->
+              <el-button type="success" plain icon="el-icon-download" @click="exportData">导出</el-button>
             </template>
             <template #menu="{ row }">
-              <el-button 
-                type="text" 
-                icon="el-icon-view" 
-                @click="handleViewDetail(row)"
-              >详情</el-button>
+              <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button>
             </template>
             <template #status="{ row }">
               <el-tag :type="getStatusTagType(row.status)">{{ mapStatus(row.status) }}</el-tag>
             </template>
             <template #keyData="{ row }">
-              <el-tooltip :content="row.address" placement="top" effect="light">
-                <span>{{ row.keyData }}</span>
-              </el-tooltip>
+              <span>{{ row.address }}</span>
             </template>
           </avue-crud>
         </div>
@@ -110,137 +50,270 @@
 
     <!-- 新建工单对话框 -->
     <el-dialog v-model="dialogVisible" title="新建工单" width="70%" :close-on-click-modal="false" @close="resetForm">
-      <el-form :model="form" :rules="rules" ref="form" label-width="100px">
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="工单名称" prop="name">
-              <el-input v-model="form.name" placeholder="请输入工单名称"></el-input>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="工单类型" prop="type">
-              <el-select v-model="form.type" placeholder="请选择工单类型">
-                <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="处理人员" prop="handler">
-              <el-select v-model="form.handler" placeholder="请选择处理人员">
-                <el-option v-for="item in handlers" :key="item.value" :label="item.label" :value="item.value" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="关联算法" prop="algorithm">
-              <el-select v-model="form.algorithm" placeholder="请选择关联算法">
-                <el-option v-for="item in algorithms" :key="item.value" :label="item.label" :value="item.value" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="位置选择">
-              <el-button @click="openMap">地图选址</el-button>
-              <span v-if="form.location" style="margin-left: 10px;">
-                已选择位置: {{ formatLocation(form.location) }}
-              </span>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="工单内容" prop="content">
-              <el-input type="textarea" v-model="form.content" rows="4" placeholder="请输入工单内容"></el-input>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="上传图片">
-              <el-upload
-                action="/api/upload"
-                list-type="picture-card"
-                :on-preview="handleUploadPreview"
-                :on-remove="handleUploadRemove"
-                :on-success="handleUploadSuccess"
-                :on-error="handleUploadError"
-                :file-list="form.photos"
-                :limit="5"
-                :multiple="true"
-                accept="image/*"
-                :before-upload="beforeUpload"
-              >
-                <i class="el-icon-plus"></i>
-                <div slot="tip" class="el-upload__tip">
-                  上传工单相关图片(支持jpg/png格式),最多5张,单张不超过5MB
+      <el-form :model="form" :rules="rules" ref="form" label-width="100px" class="create-ticket-form">
+        <!-- 基本信息 -->
+        <div class="form-section">
+          <div class="section-title">基本信息</div>
+          <el-row :gutter="12">
+            <el-col :span="12">
+              <el-form-item label="工单名称" prop="name">
+                <el-input v-model="form.name" placeholder="请输入工单名称"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="工单类型" prop="type">
+                <el-select v-model="form.type" placeholder="请选择工单类型" class="full-width">
+                  <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="12">
+            <el-col :span="12">
+              <el-form-item label="所属部门" prop="department">
+                <el-select v-model="form.department" placeholder="请选择所属部门" @change="handleDepartmentChange"
+                  class="full-width">
+                  <el-option v-for="dept in departments" :key="dept.value" :label="dept.label" :value="dept.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="处理人员" prop="handler">
+                <el-select v-model="form.handler" placeholder="请选择处理人员" :disabled="!form.department" class="full-width">
+                  <el-option v-for="user in availableHandlers" :key="user.id" :label="user.name" :value="user.id" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="12">
+            <el-col :span="12">
+              <el-form-item label="关联算法" prop="algorithm">
+                <el-select v-model="form.algorithm" placeholder="请选择关联算法" class="full-width">
+                  <el-option v-for="item in algorithms" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+
+        <!-- 修改位置信息部分 -->
+        <div class="form-section">
+          <div class="section-title">位置信息</div>
+          <el-row :gutter="12">
+            <el-col :span="24">
+              <el-form-item label="地图选址" prop="location">
+                <div class="map-select">
+                  <!-- 替换地图为按钮 -->
+                  <avue-input-map
+                    v-model="form.location"
+                    :params="mapParams"
+                    @change="handleLocationChange"
+                    type="button"
+                  >
+                    <el-button type="primary" plain>
+                      <i class="el-icon-map-location"></i> 选择位置
+                    </el-button>
+                  </avue-input-map>
+                  
+                  <!-- 添加位置信息显示 -->
+                  <div v-if="form.location && form.location.length >= 2" class="selected-location">
+                    <p>已选位置: {{ formatLocation(form.location) }}</p>
+                    <p>详细地址: {{ form.address || '获取中...' }}</p>
+                  </div>
                 </div>
-              </el-upload>
-            </el-form-item>
-          </el-col>
-        </el-row>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+
+        <!-- 工单内容 -->
+        <div class="form-section">
+          <div class="section-title">工单内容</div>
+          <el-form-item label="工单描述" prop="content">
+            <el-input type="textarea" v-model="form.content" rows="3" placeholder="请输入工单内容描述" resize="none"></el-input>
+          </el-form-item>
+          <el-form-item label="附件图片" class="upload-item">
+            <el-upload
+              ref="upload"
+              :action="'#'"
+              :auto-upload="false"
+              list-type="picture-card"
+              :on-change="handleFileChange"
+              :on-remove="handleUploadRemove"
+              :before-upload="beforeUpload"
+              :file-list="form.photos"
+              :limit="1"
+              accept="image/*"
+            >
+              <i class="el-icon-plus"></i>
+            </el-upload>
+            <div class="el-upload__tip">支持jpg/png格式图片,最多1张,单张不超过5MB</div>
+          </el-form-item>
+        </div>
       </el-form>
-      <div slot="footer">
-        <el-button @click="dialogVisible = false">取消</el-button>
-        <el-button type="primary" @click="submitForm">提交</el-button>
-      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+          <el-button size="small" type="primary" @click="submitForm">提 交</el-button>
+        </div>
+      </template>
     </el-dialog>
 
     <!-- 工单详情对话框 -->
     <el-dialog v-model="detailVisible" title="工单详情" width="80%" append-to-body>
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form label-width="100px">
-            <el-form-item label="上传照片">
-              <el-upload
-                action="/api/upload"
-                list-type="picture-card"
-                :on-preview="handlePreview"
-                :on-remove="handleRemove"
-                :file-list="currentDetail.photos"
-              >
-                <i class="el-icon-plus"></i>
-              </el-upload>
-              <div class="el-upload__tip">
-                上传相关照片(jpg、jpeg、png),单张不超过5M
+      <div class="detail-container">
+        <!-- 工单状态流程 -->
+        <div class="status-flow">
+          <el-steps :active="currentDetail.status" align-center finish-status="success">
+            <el-step 
+              title="发起任务" 
+              :description="currentDetail.creator || '未知创建人'" 
+            />
+            <el-step title="待审核" />
+            <el-step title="待处理" />
+            <el-step title="处理中" />
+            <el-step title="已完成" />
+            <el-step 
+              title="已完结" 
+              :description="currentDetail.handler || '未分配'" 
+            />
+          </el-steps>
+        </div>
+
+        <!-- 基本信息表格 -->
+        <el-table :data="formattedDetailFields" border style="width: 100%; margin-bottom: 20px;">
+          <el-table-column prop="label1" label="基本信息" width="150" />
+          <el-table-column>
+            <template #default="{ row }">
+              <template v-if="currentDetail.status === 2 && row.label1 === '工单名称'">
+                <el-input v-model="currentDetail.orderName" placeholder="请输入工单名称" />
+              </template>
+              <template v-else>{{ row.value1 }}</template>
+            </template>
+          </el-table-column>
+          <el-table-column prop="label2" label="基本信息" width="150" />
+          <el-table-column>
+            <template #default="{ row }">
+              <template v-if="currentDetail.status === 2 && row.label2 === '工单内容'">
+                <el-input v-model="currentDetail.remark" placeholder="请输入工单内容" />
+              </template>
+              <template v-else-if="currentDetail.status === 2 && row.label2 === '工单类型'">
+                <el-select v-model="currentDetail.type" placeholder="请选择工单类型">
+                  <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </template>
+              <template v-else>{{ row.value2 }}</template>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <!-- 事件处理详情 -->
+        <div v-if="[3, 4, 5].includes(currentDetail.status)" class="form-section">
+          <div class="section-title">事件处理详情</div>
+          <el-input
+            type="textarea"
+            v-model="currentDetail.processingDetail"
+            :disabled="currentDetail.status !== 3"
+            placeholder="请输入事件处理详情"
+            rows="4"
+            style="width: 100%; margin-bottom: 10px;"
+          />
+        </div>
+
+        <!-- 上传图片 -->
+        <div v-if="[3, 4].includes(currentDetail.status)" class="form-section">
+          <div class="section-title">上传图片</div>
+          <el-upload
+            ref="upload"
+            :action="'#'"
+            :auto-upload="false"
+            list-type="picture-card"
+            :on-change="handleFileChange"
+            :on-remove="handleUploadRemove"
+            :before-upload="beforeUpload"
+            :file-list="[]"
+            accept="image/*"
+          >
+            <i class="el-icon-plus"></i>
+          </el-upload>
+          <div class="el-upload__tip">支持 jpg/png 格式图片,最多 5 张,单张不超过 5MB</div>
+        </div>
+
+        <!-- 图片和地图 -->
+        <div class="media-section">
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <div class="media-box">
+                <div class="media-title">事件图片/事件视频</div>
+                <div class="media-content">
+                  <el-image
+                    v-if="currentDetail.mediaUrl"
+                    :src="currentDetail.mediaUrl"
+                    :preview-src-list="[currentDetail.mediaUrl]"
+                    fit="cover"
+                    style="width: 100%; height: 300px;"
+                  >
+                    <template #placeholder>
+                      <div class="image-placeholder">
+                        <i class="el-icon-picture-outline"></i>
+                        <span>加载中...</span>
+                      </div>
+                    </template>
+                    <template #error>
+                      <div class="image-error">
+                        <i class="el-icon-picture-outline"></i>
+                        <span>加载失败</span>
+                      </div>
+                    </template>
+                  </el-image>
+                  <div v-else class="no-media">暂无图片/视频</div>
+                </div>
               </div>
-            </el-form-item>
-          </el-form>
-        </el-col>
-        <el-col :span="12">
-          <el-form label-width="100px" class="detail-form">
-            <el-form-item label="工单编号">
-              <span>{{ currentDetail.orderNumber }}</span>
-            </el-form-item>
-            <el-form-item label="任务名称">
-              <span>{{ currentDetail.orderName }}</span>
-            </el-form-item>
-            <el-form-item label="工单状态">
-              <el-tag :type="getStatusTagType(currentDetail.status)">
-                {{ mapStatus(currentDetail.status) }}
-              </el-tag>
-            </el-form-item>
-            <el-form-item label="发起时间">
-              <span>{{ currentDetail.startTime }}</span>
-            </el-form-item>
-            <el-form-item label="发起人">
-              <span>{{ currentDetail.creator }}</span>
-            </el-form-item>
-            <el-form-item label="经纬度">
-              <span>{{ currentDetail.keyData }}</span>
-            </el-form-item>
-            <el-form-item label="详细地址">
-              <span>{{ currentDetail.address }}</span>
-            </el-form-item>
-          </el-form>
-        </el-col>
-      </el-row>
-      <template #footer>
-        <el-button @click="detailVisible = false">关闭</el-button>
-      </template>
+            </el-col>
+            <el-col :span="12">
+              <div class="media-box">
+                <div class="media-title">地图标记事件点</div>
+                <div class="media-content">
+                  <div id="map-container" style="width: 100%; height: 300px; background: #f5f5f5;">
+                    <!-- 地图容器 -->
+                    <span>地图功能待实现</span>
+                  </div>
+                </div>
+              </div>
+            </el-col>
+          </el-row>
+        </div>
+
+        <!-- 操作按钮 -->
+        <div class="dialog-footer">
+          <template v-if="currentDetail.status === 1">
+            <!-- 待审核 -->
+            <el-button type="primary" @click="approveTicket">通过</el-button>
+            <el-button type="danger" @click="rejectTicket">不通过</el-button>
+            <el-button @click="detailVisible = false">取消</el-button>
+          </template>
+          <template v-else-if="currentDetail.status === 2">
+            <!-- 待处理 -->
+            <el-button type="primary" @click="approveAndDispatch">通过并派发</el-button>
+            <el-button type="danger" @click="rejectTicket">不通过</el-button>
+            <el-button @click="detailVisible = false">取消</el-button>
+          </template>
+          <template v-else-if="currentDetail.status === 3">
+            <!-- 处理中 -->
+            <el-button type="primary" @click="completeTicket">完成工单</el-button>
+            <el-button @click="detailVisible = false">取消</el-button>
+          </template>
+          <template v-else-if="currentDetail.status === 4">
+            <!-- 已完成 -->
+            <el-button type="primary" @click="finalizeTicket">完结工单</el-button>
+            <el-button @click="detailVisible = false">取消</el-button>
+          </template>
+          <template v-else-if="currentDetail.status === 5">
+            <!-- 已完结 -->
+            <el-button @click="detailVisible = false">关闭</el-button>
+          </template>
+        </div>
+      </div>
     </el-dialog>
   </basic-container>
 </template>
@@ -276,10 +349,8 @@
         { label: "处理人A", value: "handlerA" },
         { label: "处理人B", value: "handlerB" },
       ],
-      algorithms: [
-        { label: "算法A", value: "algorithmA" },
-        { label: "算法B", value: "algorithmB" },
-      ],
+
+      algorithms: [],
       statuses: [
         { label: "待审核", value: "1" },
         { label: "待处理", value: "2" },
@@ -293,34 +364,37 @@
         stripe: true,
         menuWidth: 150,
         searchMenuSpan: 6,
+        addBtnText: "新建工单",
         viewBtn: false,
         editBtn: false,
         delBtn: false,
         menu: true,
+        page: true,
         column: [
           { label: "序号", prop: "id", width: 70 },
           { label: "工单编号", prop: "orderNumber", width: 150 },
           { label: "工单名称", prop: "orderName", width: 150 },
           { label: "所属单位", prop: "department", width: 100 },
           { label: "发起时间", prop: "startTime", width: 160 },
-          { label: "关联算法", prop: "content", width: 180 },
+          { label: "关联算法", prop: "content", width: 165 },
           { label: "工单类型", prop: "type", width: 108 },
-          { 
-            label: "关键数据", 
-            prop: "keyData", 
-            slot: true, 
-            width: 250, 
-            overHidden: true 
+          {
+            label: "工单内容",
+            prop: "address",
+            slot: true,
+            width: 250,
+            overHidden: true
           },
           { label: "创建人", prop: "creator", width: 100 },
           { label: "处理人", prop: "handler", width: 100 },
           { label: "工单状态", prop: "status", slot: true, width: 100 }
         ],
       },
-      pagination: {
-        currentPage: 1,
-        pageSize: 10,
+      page: {
         total: 0,
+        currentPage: 1,
+        pageSize: 10000,
+        pageSizes: [10000, 20000, 30000]
       },
       dialogVisible: false,
       detailVisible: false,
@@ -328,9 +402,10 @@
       form: {
         name: '',
         type: '',
+        department: '',
         handler: '',
         algorithm: '',
-        location: '',
+        location: [],  // 将存储为[经度, 纬度, 地址]格式
         address: '',
         content: '',
         photos: [],
@@ -338,12 +413,19 @@
       rules: {
         name: [{ required: true, message: '请输入工单名称', trigger: 'blur' }],
         type: [{ required: true, message: '请选择工单类型', trigger: 'change' }],
+        department: [{ required: true, message: '请选择所属部门', trigger: 'change' }],
         handler: [{ required: true, message: '请选择处理人员', trigger: 'change' }],
         content: [{ required: true, message: '请输入工单内容', trigger: 'blur' }],
       },
+      departmentUsers: {},
       loading: false,
       globalCounts: {},
       mapLoaded: false,
+      isFetching: false,
+      mapParams: {
+        zoom: 15,
+        center: [115.861365, 28.621311],  // 默认中心点
+      },
     };
   },
   created() {
@@ -353,11 +435,112 @@
   mounted() {
     this.fetchTableData();
   },
+  computed: {
+    availableHandlers() {
+      return this.form.department ? (this.departmentUsers[this.form.department] || []) : [];
+    },
+    detailTableData() {
+      return [
+        {
+          label: "工单名称",
+          value: this.currentDetail.orderName,
+          editable: this.currentDetail.status === 2,
+          type: "input",
+        },
+        {
+          label: "关键任务",
+          value: this.currentDetail.keyData,
+          editable: false,
+        },
+        {
+          label: "任务发起人",
+          value: this.currentDetail.creator,
+          editable: false,
+        },
+        {
+          label: "当前状态",
+          value: this.mapStatus(this.currentDetail.status),
+          editable: false,
+        },
+        {
+          label: "事件地址",
+          value: this.currentDetail.address,
+          editable: false,
+        },
+        {
+          label: "工单类型",
+          value: this.currentDetail.type,
+          editable: this.currentDetail.status === 2,
+          type: "select",
+          options: this.types,
+        },
+        {
+          label: "关联算法",
+          value: this.currentDetail.content,
+          editable: false,
+        },
+        {
+          label: "任务接收单位",
+          value: this.currentDetail.department,
+          editable: false,
+        },
+        {
+          label: "发起任务时间",
+          value: this.currentDetail.startTime,
+          editable: false,
+        },
+        {
+          label: "工单内容",
+          value: this.currentDetail.remark,
+          editable: this.currentDetail.status === 2,
+          type: "textarea",
+        },
+      ];
+    },
+    detailFields() {
+      return [
+        { label: "工单名称", value: this.currentDetail.orderName, editable: this.currentDetail.status === 2, type: "input" },
+        { label: "关键任务", value: this.currentDetail.keyData, editable: false },
+        { label: "任务发起人", value: this.currentDetail.creator, editable: false },
+        { label: "当前状态", value: this.mapStatus(this.currentDetail.status), editable: false },
+        { label: "事件地址", value: this.currentDetail.address, editable: false },
+        { label: "工单类型", value: this.currentDetail.type, editable: this.currentDetail.status === 2, type: "select", options: this.types },
+        { label: "关联算法", value: this.currentDetail.content, editable: false },
+        { label: "任务接收单位", value: this.currentDetail.department, editable: false },
+        { label: "发起任务时间", value: this.currentDetail.startTime, editable: false },
+        { label: "工单内容", value: this.currentDetail.remark, editable: this.currentDetail.status === 2, type: "textarea" },
+      ];
+    },
+    formattedDetailFields() {
+      const fields = [
+        { label: "工单名称", value: this.currentDetail.orderName },
+        { label: "工单类型", value: this.currentDetail.type },
+        { label: "关键数据", value: this.currentDetail.handler || '未分配' }, // 显示处理人
+        { label: "任务发起人", value: this.currentDetail.creator },
+        { label: "当前状态", value: this.mapStatus(this.currentDetail.status) },
+        { label: "事件地址", value: this.currentDetail.address }, // 包含经纬度信息
+        { label: "关联算法", value: this.currentDetail.content },
+        { label: "任务接收单位", value: this.currentDetail.department },
+        { label: "发起任务时间", value: this.currentDetail.startTime },
+        { label: "工单内容", value: this.currentDetail.remark },
+      ];
+
+      // 将字段分成两列
+      const formattedFields = [];
+      for (let i = 0; i < fields.length; i += 2) {
+        formattedFields.push({
+          label1: fields[i]?.label || "",
+          value1: fields[i]?.value || "暂无数据",
+          label2: fields[i + 1]?.label || "",
+          value2: fields[i + 1]?.value || "暂无数据",
+        });
+      }
+      return formattedFields;
+    },
+  },
   methods: {
     async loadAMapScripts() {
       try {
-        // await loadAMap();
-        // await loadAMapUI();
         this.mapLoaded = true;
       } catch (error) {
         console.error('Failed to load AMap scripts:', error);
@@ -368,21 +551,27 @@
     async fetchDropdownData() {
       try {
         const response = await getTicketInfo();
-        console.log('接口返回数据:', response.data.data);
-        const { dept_data, event_type } = response.data.data;
+        const { dept_data, event_type, ai_type } = response.data.data;
 
         this.departments = dept_data.map(item => ({
           label: item.dept_name,
           value: item.id,
         }));
 
+        this.departmentUsers = dept_data.reduce((acc, dept) => {
+          acc[dept.id] = dept.user_data || [];
+          return acc;
+        }, {});
+
         this.types = Object.entries(event_type).map(([key, value]) => ({
           label: value,
           value: key,
         }));
 
-        console.log('departments:', this.departments);
-        console.log('types:', this.types);
+        this.algorithms = ai_type.map(item => ({
+          label: item.dict_value,
+          value: item.dict_key,
+        }));
       } catch (error) {
         console.error('获取下拉框数据失败:', error);
         this.$message.error('加载下拉框数据失败');
@@ -390,146 +579,164 @@
     },
 
     async fetchTableData() {
+      if (this.isFetching) return;
+      this.isFetching = true;
       this.loading = true;
       try {
         const currentTab = this.tabs.find(tab => tab.name === this.activeTab);
         const params = {
           word_order_type: this.filters.type || undefined,
-          status: this.filters.status !== "" ? Number(this.filters.status) : currentTab?.value,
+          status: currentTab?.name === 'myTickets' ? undefined : 
+                 this.filters.status !== "" ? Number(this.filters.status) : 
+                 currentTab?.value,
           keyword: this.filters.keyword || undefined,
           dept_id: this.filters.department || undefined,
           start_date: this.filters.dateRange?.[0] ? this.formatDate(this.filters.dateRange[0]) : undefined,
           end_date: this.filters.dateRange?.[1] ? this.formatDate(this.filters.dateRange[1]).replace("00:00:00", "23:59:59") : undefined,
-          current: this.pagination.currentPage,
-          size: this.pagination.pageSize,
+          current: parseInt(this.page.currentPage),  // 确保是数字
+          size: parseInt(this.page.pageSize)        // 确保是数字
         };
-        console.log("发送的参数:", params);
+        const param = ref({
+          zoom: 10,
+          // zoomEnable: false,
+          // dragEnable: false,
+        });
+
+        const form = ref([113.10235504165291, 41.03624227495205, "内蒙古自治区乌兰察布市集宁区新体路街道顺达源广告传媒"]);
         const response = await getList(params);
         if (!response?.data?.data?.records) {
           throw new Error('接口返回数据格式不正确');
         }
 
         const { total, records } = response.data.data;
-        this.tableData = records.map(item => {
+        let filteredRecords = records;
+        
+        // 如果是"我发起的"tab,过滤数据
+        if (currentTab?.name === 'myTickets') {
+          filteredRecords = records.filter(item => 
+            String(item.create_user_id) === String(item.user_id)
+          );
+        }
+
+        this.tableData = filteredRecords.map(item => {
           const longitude = Number(item.longitude) || 0;
           const latitude = Number(item.latitude) || 0;
           return {
             id: item.id,
-            orderNumber: `EVENT${item.id}`,
-            orderName: item.event_name || '未命名',
-            department: this.departments.find(d => d.value === item.dept_id)?.label || item.dept_name || "未知单位",
-            startTime: item.create_time || '未知时间',
-            content: item.ai_types || '无内容',
-            type: this.types.find(t => t.value === item.event_dict_key)?.label || '未知类型',
+            orderNumber: item.event_num , // 修改这里:优先使用 event_num
+            orderName: item.event_name,
+            department: this.departments.find(d => d.value === item.dept_id)?.label || item.dept_name,
+            startTime: item.create_time,
+            content: item.ai_types,
+            type: this.types.find(t => t.value === item.event_dict_key)?.label,
             keyData: (!isNaN(longitude) && !isNaN(latitude))
               ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`
               : '未知位置',
-            address: item.address || '暂无地址信息',
-            creator: item.create_user || '未知创建人',
+            address: item.address ,
+            creator: item.create_user ,
             handler: item.update_user || '未分配',
             status: Number(item.status || 0),
-            photos: item.photos ? item.photos.map(p => ({ url: p })) : [],
+            // 保存原始字段
+            photo_url: item.photo_url || '',  // 保存原始 photo_url
+            video_url: item.video_url || '',  // 保存原始 video_url
             location: (!isNaN(longitude) && !isNaN(latitude)) ? [longitude, latitude] : null,
           };
         });
 
-        if (this.activeTab === 'all') {
-          this.updateGlobalCounts(records, total);
+        // 更新总数显示
+        if (currentTab?.name === 'myTickets') {
+          this.page.total = filteredRecords.length;
+        } else {
+          this.page.total = total || 0;
         }
 
-        this.pagination.total = total || 0;
+        if (this.activeTab === 'all') {
+          // 计算"我发起的"工单数量
+          const myTicketsCount = records.filter(item => 
+            String(item.create_user_id) === String(item.user_id)
+          ).length;
+          
+          // 更新全局计数,包括"我发起的"数量
+          this.updateGlobalCounts(records, total, myTicketsCount);
+        }
         this.updateTabCounts();
       } catch (error) {
         console.error("获取数据失败:", error);
         this.$message.error(error.message || "获取数据失败");
         this.tableData = [];
-        this.pagination.total = 0;
+        this.page.total = 0;
       } finally {
         this.loading = false;
+        this.isFetching = false;
       }
-    },
-
-    beforeUpload(file) {
-      const isImage = file.type.includes('image');
-      const isLt5M = file.size / 1024 / 1024 < 5;
-
-      if (!isImage) {
-        this.$message.error('只能上传图片文件!');
-        return false;
-      }
-      if (!isLt5M) {
-        this.$message.error('图片大小不能超过5MB!');
-        return false;
-      }
-      return true;
-    },
-
-    handleUploadPreview(file) {
-      this.$message.info(`预览图片:${file.name}`);
-    },
-
-    handleUploadRemove(file, fileList) {
-      this.form.photos = fileList;
-      this.$message.success(`已移除图片:${file.name}`);
-    },
-
-    handleUploadSuccess(response, file, fileList) {
-      this.form.photos = fileList;
-      this.$message.success(`图片上传成功:${file.name}`);
-    },
-
-    handleUploadError(err, file) {
-      this.$message.error(`图片上传失败:${file.name}`);
-      console.error('上传失败:', err);
-    },
-
-    async uploadFiles(files) {
-      const uploadPromises = files.map(file => {
-        return new Promise((resolve) => {
-          const formData = new FormData();
-          formData.append('file', file.raw);
-          setTimeout(() => {
-            resolve({
-              url: URL.createObjectURL(file.raw),
-              name: file.name
-            });
-          }, 1000);
-        });
-      });
-      return Promise.all(uploadPromises);
     },
 
     async submitForm() {
       this.$refs.form.validate(async (valid) => {
         if (valid) {
-          if (!this.form.location || this.form.location.length !== 2) {
+          if (!this.form.location || this.form.location.length < 2) {
             this.$message.warning('请在地图上选择位置');
             return;
           }
 
           try {
-            const unUploadedFiles = this.form.photos.filter(file => file.raw);
-            if (unUploadedFiles.length > 0) {
-              await this.uploadFiles(unUploadedFiles);
-            }
-
+            // 修改提交数据结构
             const submitData = {
-              ...this.form,
-              photos: this.form.photos.map(file => file.url || file.response?.url),
-              location: this.form.location.join(','),
-              status: 1
+              eventName: this.form.name,
+              remark: this.form.content,
+              workType: "1",
+              longitude: String(this.form.location[0]),
+              latitude: String(this.form.location[1]),
+              address: this.form.address,
+              eventDictKey: this.form.type,
+              aiType: this.form.algorithm,
+              updateUser: this.form.handler,
+              createDept: this.form.department,  // 添加所属部门ID
+              isDraft: 0
             };
 
-            await createTicket(submitData);
-            this.dialogVisible = false;
-            this.$message.success('工单创建成功');
-            this.fetchTableData();
+            // 获取文件对象
+            let file = null;
+            if (this.form.photos && this.form.photos.length > 0) {
+              file = this.form.photos[0].raw;
+            }
+
+            const response = await createTicket(submitData, file);
+            if (response.data.code === 0) {
+              this.$message.success('工单创建成功');
+              this.dialogVisible = false;
+              this.fetchTableData();
+            } else {
+              throw new Error(response.data.msg || '创建失败');
+            }
           } catch (error) {
             console.error('提交失败:', error);
-            this.$message.error('工单创建失败: ' + (error.message || '服务器错误'));
+            this.$message.error(error.message || '工单创建失败,请稍后重试');
           }
         }
       });
+    },
+
+    async handleLocationChange(val) {
+      console.log('地图选址返回值:', val);
+      
+      // 处理 Proxy 对象的值
+      let locationValue = val.value;
+      if (locationValue && locationValue.length >= 3) {
+        // 确保我们获取到实际的数组值
+        this.form.location = [locationValue[0], locationValue[1]];
+        this.form.address = locationValue[2] || '';
+        
+        console.log('解析后的位置信息:', {
+          经度: this.form.location[0],
+          纬度: this.form.location[1],
+          地址: this.form.address
+        });
+      } else {
+        console.warn('无效的位置数据');
+        this.form.location = [];
+        this.form.address = '';
+      }
     },
 
     formatDate(date) {
@@ -563,12 +770,12 @@
     handleTabChange(tab) {
       this.activeTab = tab.props?.name || tab.name;
       this.filters.status = "";
-      this.pagination.currentPage = 1;
+      this.page.currentPage = 1;
       this.fetchTableData();
     },
 
     handleSearch() {
-      this.pagination.currentPage = 1;
+      this.page.currentPage = 1;
       this.fetchTableData();
     },
 
@@ -580,17 +787,29 @@
         dateRange: [],
         status: "",
       };
-      this.pagination.currentPage = 1;
+      this.page.currentPage = 1;
       this.fetchTableData();
     },
 
-    handlePaginationChange(val) {
-      this.pagination.currentPage = val.currentPage;
-      this.pagination.pageSize = val.pageSize;
-      this.fetchTableData();
+    currentChange(currentPage) {
+      console.log('currentChange triggered, new page:', currentPage);
+      // 先更新页码,再请求数据
+      this.page.currentPage = currentPage;
+      this.$nextTick(() => {
+        this.fetchTableData();
+      });
     },
 
-    updateGlobalCounts(records, total) {
+    sizeChange(pageSize) {
+      console.log('sizeChange triggered, new size:', pageSize);
+      this.page.pageSize = pageSize;
+      this.page.currentPage = 1;
+      this.$nextTick(() => {
+        this.fetchTableData();
+      });
+    },
+
+    updateGlobalCounts(records, total, myTicketsCount) {
       const counts = {
         all: total,
         pending: 0,
@@ -598,7 +817,7 @@
         inProgress: 0,
         completed: 0,
         closed: 0,
-        myTickets: 0
+        myTickets: myTicketsCount || 0  // 添加"我发起的"计数
       };
 
       records.forEach(item => {
@@ -635,9 +854,10 @@
       this.form = {
         name: '',
         type: '',
+        department: '',
         handler: '',
         algorithm: '',
-        location: '',
+        location: [],  // 将存储为[经度, 纬度, 地址]格式
         address: '',
         content: '',
         photos: [],
@@ -655,9 +875,27 @@
     },
 
     handleViewDetail(row) {
+      // 添加调试日志
+      console.log('原始行数据:', row);
+      
+      const mediaUrl = row.photo_url || row.video_url;
+      console.log('媒体信息:', {
+        photo_url: row.photo_url,
+        video_url: row.video_url,
+        mediaUrl: mediaUrl,
+        rowData: JSON.stringify(row)  // 添加完整行数据打印
+      });
+      
+      const longitude = row.location?.[0] || '未知经度';
+      const latitude = row.location?.[1] || '未知纬度';
+      const addressWithCoordinates = `${row.address || '暂无地址信息'} (${longitude}, ${latitude})`;
+
       this.currentDetail = {
         ...row,
-        photos: row.photos || [],
+        mediaUrl: mediaUrl || '',
+        photos: mediaUrl ? [{ url: mediaUrl }] : [],
+        address: addressWithCoordinates,
+        handler: row.handler || '未分配', // 设置处理人
       };
       this.detailVisible = true;
     },
@@ -675,23 +913,32 @@
     },
 
     refreshChange() {
+      if (this.isFetching) return;
       this.fetchTableData();
     },
 
     onLoad() {
+      if (this.isFetching) return;
       this.fetchTableData();
     },
 
     async exportData() {
       try {
         this.loading = true;
+        const currentTab = this.tabs.find(tab => tab.name === this.activeTab);
+        
+        // 使用与查询列表相同的参数构造逻辑
         const params = {
-          keyword: this.filters.keyword || undefined,
           word_order_type: this.filters.type || undefined,
-          status: this.filters.status || undefined,
+          status: currentTab?.name === 'myTickets' ? undefined : 
+                 this.filters.status !== "" ? Number(this.filters.status) : 
+                 currentTab?.value, // 使用当前tab的状态值
+          keyword: this.filters.keyword || undefined,
           dept_id: this.filters.department || undefined,
           start_date: this.filters.dateRange?.[0] ? this.formatDate(this.filters.dateRange[0]) : undefined,
           end_date: this.filters.dateRange?.[1] ? this.formatDate(this.filters.dateRange[1]) : undefined,
+          current: 1,
+          size: 10000
         };
 
         const response = await getList(params);
@@ -699,33 +946,109 @@
           throw new Error('接口返回数据格式不正确');
         }
 
-        const records = response.data.data.records;
-        const exportData = records.map(item => ({
-          工单编号: item.wayline_job_id || '',
-          工单名称: item.event_name || '',
-          所属单位: this.departments.find(d => d.value === item.deptId)?.label || '未知单位',
-          发起时间: item.create_time || '',
-          工单内容: item.ai_types || '',
-          工单类型: this.types.find(t => t.value === item.event_dict_key)?.label || '未知类型',
-          经纬度: `${item.longitude || '未知'}, ${item.latitude || '未知'}`,
-          详细地址: item.address || '暂无地址信息',
-          创建人: item.create_user || '未知创建人',
-          处理人: item.update_user || '未分配',
-          工单状态: this.mapStatus(Number(item.status || 0)),
-        }));
+        const { records } = response.data.data;
+        
+        // 使用与查询列表相同的过滤逻辑
+        let filteredRecords = records;
+        if (currentTab?.name === 'myTickets') {
+          filteredRecords = records.filter(item => 
+            String(item.create_user_id) === String(item.user_id)
+          );
+        }
 
-        export_json_to_excel(
-          ['工单编号', '工单名称', '所属单位', '发起时间', '工单内容', '工单类型', '经纬度', '详细地址', '创建人', '处理人', '工单状态'],
-          exportData,
-          '工单数据'
-        );
+        const exportData = filteredRecords.map(item => {
+          const longitude = Number(item.longitude) || 0;
+          const latitude = Number(item.latitude) || 0;
+          return {
+            工单编号: item.event_num || '',
+            工单名称: item.event_name || '',
+            所属单位: item.dept_name || '',
+            发起时间: item.create_time || '',
+            关联算法: item.ai_types || '',
+            工单内容: item.address || '',
+            工单类型: this.types.find(t => t.value === item.event_dict_key)?.label || '',
+            经纬度: (!isNaN(longitude) && !isNaN(latitude)) ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}` : '',
+            创建人: item.create_user || '',
+            处理人: item.update_user || '',
+            工单状态: this.mapStatus(Number(item.status || 0))
+          };
+        });
+
+        if (exportData.length === 0) {
+          this.$message.warning('没有数据可供导出');
+          return;
+        }
+
+        const headers = [
+          '工单编号',
+          '工单名称', 
+          '所属单位',
+          '发起时间',
+          '关联算法',
+          '工单内容',
+          '工单类型',
+          '经纬度',
+          '创建人',
+          '处理人',
+          '工单状态'
+        ];
+
+        export_json_to_excel(headers, exportData, '工单数据');
         this.$message.success('数据导出成功');
       } catch (error) {
         console.error('导出失败:', error);
-        this.$message.error('数据导出失败');
+        this.$message.error(error.message || '导出失败,请稍后重试');
       } finally {
         this.loading = false;
       }
+    },
+
+    handleDepartmentChange(deptId) {
+      this.form.handler = '';
+    },
+
+    // 文件改变时的钩子
+    handleFileChange(file, fileList) {
+      this.form.photos = fileList;
+      this.currentDetail.photos = fileList;
+    },
+
+    // 文件移除时的钩子
+    handleUploadRemove(file, fileList) {
+      this.form.photos = fileList;
+      this.currentDetail.photos = fileList;
+    },
+
+    // 上传前的验证
+    beforeUpload(file) {
+      const isImage = file.type.includes('image');
+      const isLt5M = file.size / 1024 / 1024 < 5;
+
+      if (!isImage) {
+        this.$message.error('只能上传图片文件!');
+        return false;
+      }
+      if (!isLt5M) {
+        this.$message.error('图片大小不能超过5MB!');
+        return false;
+      }
+      return true;
+    },
+
+    approveTicket() {
+      this.$message.success("工单已通过并派发");
+    },
+    rejectTicket() {
+      this.$message.error("工单未通过");
+    },
+    submitProcessing() {
+      this.$message.success("处理详情已提交");
+    },
+    markAsCompleted() {
+      this.$message.success("工单已标记为完成");
+    },
+    completeTicket() {
+      this.$message.success("工单已完成");
     },
   },
   watch: {
@@ -757,7 +1080,7 @@
   }
 
   .date-picker {
-    width: 240px;
+    width: 150px;
   }
 }
 
@@ -800,11 +1123,11 @@
   width: 100%;
   display: flex;
   flex-wrap: wrap;
-  
+
   :deep(.el-upload-list__item) {
     transition: all 0.3s ease;
   }
-  
+
   :deep(.el-upload-list__item:hover) {
     background-color: #f5f7fa;
   }
@@ -815,4 +1138,215 @@
   color: #909399;
   margin-top: 7px;
 }
+
+.create-ticket-form {
+  padding: 10px;
+
+  .form-section {
+    margin-bottom: 15px;
+    background: #f8f9fa;
+    border-radius: 4px;
+    padding: 12px;
+
+    .section-title {
+      font-size: 14px;
+      font-weight: 500;
+      color: #303133;
+      margin-bottom: 12px;
+      padding-left: 8px;
+      border-left: 3px solid #409EFF;
+    }
+
+    .el-form-item {
+      margin-bottom: 12px;
+    }
+  }
+
+  .map-select {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+
+    .location-text {
+      color: #606266;
+      font-size: 13px;
+    }
+  }
+
+  .upload-item {
+    margin-bottom: 0;
+  }
+
+  .ticket-upload {
+    :deep(.el-upload--picture-card) {
+      width: 100px;
+      height: 100px;
+      line-height: 100px;
+      margin: 0 8px 8px 0;
+    }
+
+    :deep(.el-upload-list--picture-card .el-upload-list__item) {
+      width: 100px;
+      height: 100px;
+      margin: 0 8px 8px 0;
+    }
+  }
+
+  .el-upload__tip {
+    font-size: 12px;
+    color: #909399;
+    line-height: 1.2;
+    margin-top: 5px;
+  }
+}
+
+.dialog-footer {
+  text-align: right;
+  padding-top: 10px;
+}
+
+.map-container {
+  width: 100%;
+  height: 400px;
+  margin-bottom: 15px;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  overflow: hidden;
+
+  :deep(.el-input-map) {
+    height: 100%;
+  }
+}
+
+.location-info {
+  margin-top: 10px;
+  padding: 10px;
+  background-color: #f5f7fa;
+  border-radius: 4px;
+
+  p {
+    margin: 5px 0;
+    color: #606266;
+    font-size: 14px;
+  }
+}
+
+.map-select {
+  display: flex;
+  align-items: flex-start;
+  gap: 15px;
+
+  .selected-location {
+    flex: 1;
+    padding: 5px 10px;
+    background-color: #f5f7fa;
+    border-radius: 4px;
+    
+    p {
+      margin: 5px 0;
+      color: #606266;
+      font-size: 14px;
+    }
+  }
+}
+
+.preview-image {
+  border-radius: 4px;
+  overflow: hidden;
+  background-color: #f5f7fa;
+}
+
+.image-placeholder,
+.image-error,
+.no-media {
+  height: 200px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  color: #909399;
+  background-color: #f5f7fa;
+  border-radius: 4px;
+  
+  i {
+    font-size: 32px;
+    margin-bottom: 8px;
+  }
+}
+
+.no-media {
+  border: 1px dashed #d9d9d9;
+}
+
+.detail-container {
+  padding: 20px;
+}
+
+.status-flow {
+  margin-bottom: 20px;
+}
+
+.basic-info {
+  margin-bottom: 20px;
+}
+
+.media-section {
+  margin-bottom: 20px;
+}
+
+.media-box {
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  padding: 10px;
+  background: #fff;
+}
+
+.media-title {
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+
+.media-content {
+  position: relative;
+  height: 300px;
+}
+
+.image-placeholder,
+.image-error,
+.no-media {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+  color: #909399;
+  background-color: #f5f7fa;
+  border-radius: 4px;
+}
+
+.image-placeholder i,
+.image-error i {
+  font-size: 32px;
+  margin-bottom: 8px;
+}
+
+.info-table {
+  margin-bottom: 20px;
+}
+
+.info-item {
+  display: flex;
+  margin-bottom: 10px;
+}
+
+.info-label {
+  font-weight: bold;
+  width: 120px;
+  color: #606266;
+}
+
+.info-value {
+  flex: 1;
+  color: #303133;
+  word-break: break-word;
+}
 </style>
\ No newline at end of file

--
Gitblit v1.9.3