riku
2025-07-29 056ea576d820729878ffd62cd54cd7598e72d07e
新增图片超出限制,无法选中功能
已修改10个文件
已添加1个文件
258 ■■■■■ 文件已修改
src/api/clue/clueApi.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/clue/clueTaskApi.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/userApi.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/map/baseMapUtil.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test.js 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/overlay-clue/list/ClueManage.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/overlay-clue/list/components/ClueList.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/overlay-clue/report/ClueReport.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/overlay-clue/report/components/ClueReportQuestion.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/overlay-clue/report/components/QuestionDetail.vue 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/clue/clueApi.js
@@ -40,7 +40,7 @@
   */
  pushClue(clueId) {
    return $clue
      .post(`clue/push?clueId=${clueId}`)
      .post(`clue/push?clueId=${clueId}`, {})
      .then((res) => res.data);
  }
};
src/api/clue/clueTaskApi.js
@@ -44,5 +44,20 @@
   */
  deleteClueTask(clueTask) {
    return $clue.post(`clue/task/delete`, clueTask);
  },
  /**
   * å®Œæˆçº¿ç´¢ä»»åŠ¡
   * @param {*} clueTaskId
   * @returns
   */
  finishClueTask(clueTaskId) {
    return $clue.post(
      `clue/task/finish`,
      {},
      {
        params: { clueTaskId }
      }
    );
  }
};
src/api/fysp/userApi.js
@@ -28,7 +28,7 @@
   * è‡ªåŠ¨åˆ›å»ºè´¦æˆ·
   */
  autoCreateAccount(sId) {
    return $fysp.post(`userinfo/create?sceneId=${sId}`).then((res) => res.data);
    return $fysp.post(`userinfo/create?sceneId=${sId}`, {}).then((res) => res.data);
  },
  /**
   * èŽ·å–åœºæ™¯å¯¹åº”çš„é£žç¾½çŽ¯å¢ƒç³»ç»Ÿç”¨æˆ·id
src/components.d.ts
@@ -23,6 +23,7 @@
    ElForm: typeof import('element-plus/es')['ElForm']
    ElFormItem: typeof import('element-plus/es')['ElFormItem']
    ElIcon: typeof import('element-plus/es')['ElIcon']
    ElImage: typeof import('element-plus/es')['ElImage']
    ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
    ElInput: typeof import('element-plus/es')['ElInput']
    ElOption: typeof import('element-plus/es')['ElOption']
@@ -47,4 +48,7 @@
    RouterLink: typeof import('vue-router')['RouterLink']
    RouterView: typeof import('vue-router')['RouterView']
  }
  export interface ComponentCustomProperties {
    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
  }
}
src/components/map/baseMapUtil.js
@@ -184,12 +184,12 @@
    }
  },
  gpsConvert(gps) {
    return new Promise((reject) => {
    return new Promise((resolve) => {
      // å‚数说明:需要转换的坐标,需要转换的坐标类型,转换成功后的回调函数
      AMap.convertFrom(gps, 'baidu', function (status, result) {
        if (result.info === 'ok') {
          var lnglats = result.locations; // è½¬æ¢åŽçš„高德坐标 Array.<LngLat>
          reject(lnglats[0]);
          resolve(lnglats[0]);
        }
      });
    });
src/test.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
const PI = 3.1415926535897932384626;
const a = 6378245.0; //长半轴
const ee = 0.00669342162296594323; //扁率/*** GCJ02 è½¬æ¢ä¸º WGS84* @param lng* @param lat* @returns {*[]}*/
function transformlat(lng, lat) {
  // lat = +lat lng = +lng
  let ret =
    -100.0 +
    2.0 * lng +
    3.0 * lat +
    0.2 * lat * lat +
    0.1 * lng * lat +
    0.2 * Math.sqrt(Math.abs(lng));
  ret +=
    ((20.0 * Math.sin(6.0 * lng * PI) +
      20.0 * Math.sin(2.0 * lng * PI)) *
      2.0) /
    3.0;
  ret +=
    ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) *
      2.0) /
    3.0;
  ret +=
    ((160.0 * Math.sin((lat / 12.0) * PI) +
      320 * Math.sin((lat * PI) / 30.0)) *
      2.0) /
    3.0;
  return ret;
}
function transformlng(lng, lat) {
  // lat = +latlng = +lng
  let ret =
    300.0 +
    lng +
    2.0 * lat +
    0.1 * lng * lng +
    0.1 * lng * lat +
    0.1 * Math.sqrt(Math.abs(lng));
  ret +=
    ((20.0 * Math.sin(6.0 * lng * PI) +
      20.0 * Math.sin(2.0 * lng * PI)) *
      2.0) /
    3.0;
  ret +=
    ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) *
      2.0) /
    3.0;
  ret +=
    ((150.0 * Math.sin((lng / 12.0) * PI) +
      300.0 * Math.sin((lng / 30.0) * PI)) *
      2.0) /
    3.0;
  return ret;
}
/**
 * åˆ¤æ–­æ˜¯å¦åœ¨å›½å†…,不在国内则不做偏移
 * @param lng
 * @param lat
 * @returns {boolean}
 */
function out_of_china(lng, lat) {
  // çº¬åº¦3.86~53.55,经度73.66~135.05
  return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
}
/**
 * é«˜å¾·åœ°å›¾åæ ‡è½¬GPS坐标算法
 */
function gcj02towgs84(_lng, _lat) {
  // lat = +latlng = +lng
  const lng = parseFloat(_lng);
  const lat = parseFloat(_lat);
  if (out_of_china(lng, lat)) {
    return [lng, lat];
  } else {
    let dlat = transformlat(lng - 105.0, lat - 35.0);
    let dlng = transformlng(lng - 105.0, lat - 35.0);
    let radlat = (lat / 180.0) * PI;
    let magic = Math.sin(radlat);
    magic = 1 - ee * magic * magic;
    let sqrtmagic = Math.sqrt(magic);
    dlat =
      (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
    dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
    let mglat =
      Math.round((lat * 2 - lat - dlat) * 1000000) / 1000000;
    let mglng =
      Math.round((lng * 2 - lng - dlng) * 1000000) / 1000000;
    return [mglng, mglat];
  }
}
const coor = [
  [121.451515, 31.312769],
  [121.472702, 31.243941],
  [121.472912, 31.243879],
  [121.475128, 31.245564],
  [121.473722, 31.246219],
  [121.474832, 31.259213],
  [121.475602, 31.261579],
  [121.474975, 31.260291],
  [121.474381, 31.259773],
  [121.47412, 31.261534],
  [121.456066, 31.313411]
];
coor.forEach((e) => {
  const res = gcj02towgs84(e[0], e[1]);
  console.log(res);
});
src/views/overlay-clue/list/ClueManage.vue
@@ -13,11 +13,11 @@
        >拉取线索</el-button
      >
    </div>
    <el-scrollbar height="70vh" class="p-h-1">
    <el-scrollbar height="70vh" class="p-h-1" v-loading="loading">
      <ClueList :dataList="clueList" @itemSelected="selectClue">
      </ClueList>
    </el-scrollbar>
    <el-row justify="space-between" class="p-8">
    <el-scrollbar v-show="showPage" class="p-8">
      <el-pagination
        size="small"
        v-model:current-page="currentPage"
@@ -27,7 +27,7 @@
        layout="total, sizes, pager"
        :total="total"
      />
    </el-row>
    </el-scrollbar>
  </div>
</template>
@@ -37,7 +37,7 @@
import clueApi from '@/api/clue/clueApi';
import { onMapMounted } from '@/components/map/baseMap';
import moment from 'moment';
import { ref, onMounted, reactive } from 'vue';
import { ref, onMounted, reactive, watch } from 'vue';
const emits = defineEmits('itemSelected');
@@ -46,13 +46,23 @@
// çº¿ç´¢æ¸…单
const clueList = ref([]);
const currentPage = ref(1);
const pageSize = ref(100);
const pageSize = ref(50);
const total = ref(0);
const showPage = ref(true);
const loading = ref(false);
watch([currentPage, pageSize], (nV, oV) => {
  if (nV[0] != oV[0] || nV[1] != oV[1]) {
    getClues();
  }
});
/**
 * æŸ¥è¯¢å·²ä¸‹å‘的线索清单
 */
const getClues = function () {
  showPage.value = true;
  loading.value = true;
  let sTime;
  let eTime;
  if (updateTime.value) {
@@ -71,16 +81,22 @@
      .then((res) => {
        total.value = res.head.totalCount;
        clueList.value = res.data;
      });
      })
      .finally(() => (loading.value = false));
  });
};
function fetchRemoteClue() {
  showPage.value = false;
  loading.value = true;
  const time = moment(updateTime.value).format('YYYY-MM-DD HH:mm:ss');
  onMapMounted(() => {
    clueApi.fetchRemoteClue(time).then((res) => {
      clueList.value = res;
    });
    clueApi
      .fetchRemoteClue(time)
      .then((res) => {
        clueList.value = res;
      })
      .finally(() => (loading.value = false));
  });
}
src/views/overlay-clue/list/components/ClueList.vue
@@ -33,10 +33,18 @@
            <el-row align="middle">
              <el-text type="info" size="small">结论:</el-text>
              <el-tag
                v-if="!isInternal"
                :type="item.cuploaded ? 'success' : 'danger'"
                effect="dark"
              >
                {{ item.cuploaded ? '已推送' : '未推送' }}
              </el-tag>
              <el-tag
                v-else
                :type="item.conclusionCount > 0 ? 'success' : 'danger'"
                effect="dark"
              >
                {{ item.conclusionCount > 0 ? '已填报' : '未填报' }}
              </el-tag>
            </el-row>
            <el-divider direction="vertical" />
@@ -85,6 +93,12 @@
var _marker;
export default {
  inject: {
    // æ˜¯å¦æ˜¯å†…部线索相关操作
    isInternal: {
      default: false
    }
  },
  props: {
    dataList: Array
  },
src/views/overlay-clue/report/ClueReport.vue
@@ -25,6 +25,30 @@
      </div>
    </el-button>
    <el-button
      v-else-if="clueTask"
      class="push-btn"
      :type="clueTask.finished ? 'success' : 'danger'"
      @click="finishTask"
      :disabled="clueTask.finished"
    >
      <div class="flex-col">
        <template v-if="clueTask.finished">
          <el-icon><Check /></el-icon>
          <div>ä»»</div>
          <div>务</div>
          <div>完</div>
          <div>成</div>
        </template>
        <template v-else>
          <el-icon><Upload /></el-icon>
          <div>结</div>
          <div>束</div>
          <div>ä»»</div>
          <div>务</div>
        </template>
      </div>
    </el-button>
    <el-button
      class="task-btn"
      :type="clueTask ? 'success' : 'danger'"
      @click="publishTask"
@@ -128,6 +152,7 @@
    },
    pushClue() {
      return clueApi.pushClue(this.clueData.cid).then((res) => {
        this.finishTask();
        this.$emit('pushed', res);
      });
    },
@@ -153,6 +178,21 @@
    handelClueTaskEdit() {
      this.getClueTask();
      this.$emit('onClueTaskChange');
    },
    finishTask() {
      useMessageBoxTip({
        confirmMsg: '是否结束线索任务?',
        confirmTitle: '结束线索任务',
        onConfirm: () => {
          return clueTaskApi
            .finishClueTask(this.clueTask.guid)
            .then((res) => {
              if (res.data == 1) {
                this.clueTask.finished = true;
              }
            });
        }
      });
    }
  }
};
src/views/overlay-clue/report/components/ClueReportQuestion.vue
@@ -26,9 +26,13 @@
          label="问题名称"
          :content="item.cqName"
        />
        <DescriptionsListItem
        <!-- <DescriptionsListItem
          label="所在街镇"
          :content="item.cqStreet"
        /> -->
        <DescriptionsListItem
          label="详细地址"
          :content="item.cqAddress"
        />
        <DescriptionsListItem
          label="问题描述"
src/views/overlay-clue/report/components/QuestionDetail.vue
@@ -90,9 +90,10 @@
          <el-icon><Plus /></el-icon>
          <template #file="{ file }">
            <div>
              <img
              <el-image
                class="el-upload-list__item-thumbnail"
                :src="file.url"
                fit="cover"
                alt=""
              />
              <span class="el-upload-list__item-actions">
@@ -122,7 +123,7 @@
          <template #tip>
            <div class="el-upload__tip">
              {{
                `请选择小于500kb的jpg/png图片,最多${maxImageCount}å¼ `
                `请选择小于5MB的jpg/png图片,最多${maxImageCount}å¼ `
              }}
            </div>
          </template>
@@ -150,9 +151,7 @@
  <MapSearch
    v-model:show="mapDialogShow"
    :defaultCoor="
      formObj.coordinate
        ? formObj.coordinate.split(',')
        : undefined
      formObj.coordinate ? formObj.coordinate.split(',') : undefined
    "
    @on-submit="selectAddress"
  ></MapSearch>
@@ -166,6 +165,9 @@
import clueQuestionApi from '@/api/clue/clueQuestionApi';
import { $clue } from '@/api/index';
import MapSearch from '@/components/map/MapSearch.vue';
// å›¾ç‰‡é™å®šå¤§å°ï¼ˆå•位:B)
const IMG_MAX_SIZE = 4 * 1024 * 1024;
// å†³å®šå½“前是否是内部线索相关操作
const isInternal = inject('isInternal', false);
@@ -246,7 +248,18 @@
}
function handleFileChange(file, files) {
  fileList.value = files;
  // console.log('fileSelect', file);
  // åˆ¤æ–­
  if (file.size > IMG_MAX_SIZE) {
    const index = files.indexOf(file);
    files.splice(index, 1);
    ElMessage({
      message: '图片大小超过限制',
      type: 'error'
    });
  } else {
    fileList.value = files;
  }
  edit.value = true;
}