hejianhao
2026-01-23 b5c8427a96b4f1fa6c39f88920685fa12a109097
feat(workList): 实现工作内容管理功能并优化UI交互

- 新增工作内容详情查看、编辑、删除和状态切换功能
- 为搜索框和日期选择器添加清除按钮
- 修复工作列表跳转详情页的参数传递问题
- 优化图片预览和上传组件的交互逻辑
- 统一使用Element UI的消息提示组件
6个文件已修改
256 ■■■■■ 已修改文件
screen/src/view/home/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/home/service.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/subentry/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/workList/detail.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/workList/index.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/workList/service.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/home/index.vue
@@ -598,6 +598,7 @@
  getStoryList,
  getProjectSelect,
  getWorkPresentationList,
  getprojectTooltip,
} from "./service";
export default {
@@ -636,6 +637,7 @@
      activeTabs: "本周",
      workListData: [],
      VUE_APP_IMAGE_BASE_URL: process.env.VUE_APP_IMAGE_BASE_URL,
      projectList: [],
    };
  },
  watch: {
@@ -748,7 +750,7 @@
      this.$router.push({
        path: "/workList/detail",
        query: {
          id: item,
          id: item.id,
        },
      });
    },
@@ -1004,6 +1006,9 @@
          level: level,
        },
      });
      marker.on("click", (item) => {
        console.log(item);
      });
      return marker;
    },
    updateMarkerVisibility() {
screen/src/view/home/service.js
@@ -26,4 +26,11 @@
    method: 'get',
    params
  })
}
export const getprojectTooltip = async (params) => {
  return request(`/project/getProjectDetail/{id}`, {
    method: 'get',
    params
  })
}
screen/src/view/subentry/index.vue
@@ -20,7 +20,7 @@
            <el-date-picker v-model="monthrange" ref="monthrangeRef" type="monthrange" placeholder=""
              :disabled="activeTabs != '自定义'">
            </el-date-picker>
            <div class="absolute w100 h100 flex a-center c-fff fs--14 SHS">
            <div class="absolute h100 flex a-center c-fff fs--14 SHS" style="width: calc(100% - 40px)">
              <div class="flex a-center flex1 shrink0 gap--13">
                <img src="../../assets/img/home/Shape@2x (6).png" class="w--13 h--13 shrink0" />
                <div style="width: calc(100% - 20px)" v-if="dateTxt1">
screen/src/view/workList/detail.vue
@@ -10,9 +10,9 @@
          class="w--22 h--20 shrink0 mr--13 cursor-pointer"
        />
      </div>
      <div class="bgcolor1 mt--25 oa" style="height: 900px;">
      <div class="bgcolor1 mt--25 oa" style="height: 900px">
        <div class="fs--30 lh--30 c-fff SHSBold">
          德国模德机床中国总部及研发生产基地项目落户成都东部新区
          {{ detailData.title }}
        </div>
        <div class="flex a-center gap--20 mt--24">
          <div class="flex a-center">
@@ -20,23 +20,23 @@
              src="../../assets/img/home/Shape@2x (3).png"
              class="mr--6 w--10 h--9"
            />
            <div class="SHSN fs--12 lh--12 c-fff">2025年11月10日</div>
            <div class="SHSN fs--12 lh--12 c-fff">
              {{ detailData.createTime }}
            </div>
          </div>
          <div class="lh--20 px--8 br--10 fs--12 bgcolor2 c-fff SHSBold">
            工作视察
          </div>
        </div>
        <div class="mt--18 fs--14 c-fff SHSN">
          德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区德国模德机床中国总部及研发生产基地项目落户成都东部新区
          {{ detailData.intro }}
        </div>
        <div class="mt--26 flex flex-column a-center gap--18">
          <img
            style="width: 730px;height: 348px;"
            src="../../assets/img/home/Shape@2x (3).png"
          />
          <img
            style="width: 730px;height: 348px;"
            src="../../assets/img/home/Shape@2x (3).png"
            v-for="(item, index) in detailData.img.split(',')"
            :key="index"
            style="width: 100%; height: 100%"
            :src="item"
          />
        </div>
      </div>
@@ -47,15 +47,22 @@
<script>
import HeaderBox from "../header/index.vue";
import moment from "moment";
import { getWorkPresentationDetail } from "./service";
export default {
  components: { HeaderBox },
  props: {},
  data() {
    return {};
    return {
      detailData: {},
    };
  },
  computed: {},
  watch: {},
  created() {},
  created() {
    getWorkPresentationDetail(this.$route.query.id).then((res) => {
      this.detailData = res;
    });
  },
  mounted() {},
  methods: {
    backFun() {
screen/src/view/workList/index.vue
@@ -18,26 +18,33 @@
          >
            <el-select
              filterable
              v-model="projectId"
              v-model="searchParams.type"
              placeholder="请选择工作类型"
              class="flex1"
            >
              <el-option
                v-for="item in [1, 2]"
                :key="item"
                :label="item"
                :value="item"
                v-for="item in [{ label: '视察工作', value: 1 }]"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
            <img
              src="../../assets/img/down-circle@2x.png"
              class="w--15 h--16 shrink0"
            />
            <div class="flex a-center gap--5">
              <i
                @click.stop="(searchParams.type = ''), getlist()"
                class="el-icon-circle-close c-fff cursor-pointer"
                v-show="searchParams.type"
              />
              <img
                src="../../assets/img/down-circle@2x.png"
                class="w--15 h--16 shrink0"
              />
            </div>
          </div>
          <div
            @click="handleClick"
            class="flex a-center j-between px--20 w--350 h--40 relative bgcolor1 picker"
            class="flex a-center relative j-between px--20 w--350 h--40 relative bgcolor1 picker"
          >
            <el-date-picker
              v-model="monthrange"
@@ -46,7 +53,10 @@
              placeholder=""
            >
            </el-date-picker>
            <div class="absolute w100 h100 flex a-center c-fff fs--14 SHS">
            <div
              class="absolute h100 flex a-center c-fff fs--14 SHS"
              style="width: calc(100% - 40px)"
            >
              <div class="flex a-center flex1 shrink0 gap--13">
                <img
                  src="../../assets/img/home/Shape@2x (6).png"
@@ -68,9 +78,14 @@
                <div v-else>请选择日期</div>
              </div>
            </div>
            <i
              @click.stop="clearDate"
              class="el-icon-circle-close c-fff cursor-pointer absolute top--10 right--10"
              v-show="dateTxt1"
            />
          </div>
          <div
            class="flex a-center j-between w--300 pl--20 h--40 relative bgcolor1 searchBox"
            class="relative flex a-center j-between w--300 pl--20 h--40 relative bgcolor1 searchBox"
          >
            <el-input
              filterable
@@ -78,7 +93,17 @@
              placeholder="请输入搜索内容"
              class="flex1"
            />
            <div @click="getlist" class="btn SHSR">搜索</div>
            <div
              class="flex a-center gap--5 absolute shrink0"
              style="top: -2px; right: -2px"
            >
              <i
                @click.stop="(searchParams.content = ''), getlist()"
                class="el-icon-circle-close c-fff cursor-pointer"
                v-show="searchParams.content"
              />
              <div @click="getlist" class="btn SHSR">搜索</div>
            </div>
          </div>
        </div>
        <div
@@ -130,11 +155,29 @@
            <el-button type="text" class="btnColor" @click="toDetail(row)"
              >详情</el-button
            >
            <el-button type="text" class="btnColor" @click="editForm(row)"
            <el-button
              type="text"
              class="btnColor"
              style="margin-left: 0"
              @click="editForm(row)"
              >编辑</el-button
            >
            <el-button type="text" class="btnColor">删除</el-button>
            <el-button type="text" class="btnColor">隐藏</el-button>
            <el-popconfirm
              title="是否确认删除此工作内容?"
              @confirm="confirmDelete(row)"
            >
              <el-button slot="reference" type="text" class="btnColor"
                >删除</el-button
              >
            </el-popconfirm>
            <el-popconfirm
              :title="`是否确认${row.state == 1 ? '隐藏' : '展示'}此工作内容?`"
              @confirm="confirmState(row)"
            >
              <el-button slot="reference" type="text" class="btnColor">{{
                row.state == 1 ? "隐藏" : "展示"
              }}</el-button>
            </el-popconfirm>
          </template>
        </el-table-column>
      </CustomTable>
@@ -143,7 +186,7 @@
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage"
          :page-sizes="[100, 200, 300, 400]"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="searchParams.pageSize"
          :total="totalSizes"
        />
@@ -269,16 +312,19 @@
        </div>
      </div>
    </CustomDialog>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="" />
    </el-dialog>
  </div>
</template>
<script>
import HeaderBox from "../header/index.vue";
import moment from "moment";
import { getWorkPresentationList, addWorkPresentation } from "./service";
import {
  getWorkPresentationList,
  addWorkPresentation,
  updateWorkPresentation,
  operateWorkPresentation,
  deleteWorkPresentation,
} from "./service";
export default {
  components: { HeaderBox },
  props: {},
@@ -311,8 +357,6 @@
      },
      formData: {},
      listData: [],
      dialogImageUrl: "",
      dialogVisible: false,
    };
  },
  computed: {},
@@ -340,6 +384,28 @@
  },
  mounted() {},
  methods: {
    clearDate() {
      this.dateTxt1 = "";
      this.dateTxt2 = "";
      this.searchParams.time = "";
      this.monthrange = null;
      this.getlist();
    },
    confirmState(row) {
      operateWorkPresentation({ id: row.id }).then((res) => {
        this.$message.success("修改成功");
        this.getlist();
      });
    },
    confirmDelete(row) {
      deleteWorkPresentation(row.id).then((res) => {
        this.$message.success("删除成功");
        this.getlist();
      });
    },
    openImgDialog(img) {
      this.imgArr = img.split(",");
      this.previewVisible = true;
@@ -347,43 +413,23 @@
    saveForm() {
      if (!this.formData.title) {
        Message({
          message: "请输入工作标题",
          type: "warning",
          duration: 1500,
        });
        this.$message.warning("请输入工作标题");
        return;
      }
      if (!this.formData.type) {
        Message({
          message: "请选择工作类型",
          type: "warning",
          duration: 1500,
        });
        this.$message.warning("请选择工作类型");
        return;
      }
      if (!this.formData.intro) {
        Message({
          message: "请输入工作标简介",
          type: "warning",
          duration: 1500,
        });
        this.$message.warning("请输入工作标简介");
        return;
      }
      if (!this.formData.state) {
        Message({
          message: "请选择展示状态",
          type: "warning",
          duration: 1500,
        });
        this.$message.warning("请选择展示状态");
        return;
      }
      if (!this.fileList.length) {
        Message({
          message: "请上传工作图片",
          type: "warning",
          duration: 1500,
        });
        this.$message.warning("请上传工作图片");
        return;
      }
@@ -392,7 +438,8 @@
        clientId: localStorage.getItem("clientId"),
      };
      obj.img = this.fileList.map((item) => item.url).join(",");
      addWorkPresentation(obj).then((res) => {
      let api = obj.id ? updateWorkPresentation : addWorkPresentation;
      api(obj).then((res) => {
        this.closeForm();
        this.getlist();
      });
@@ -406,19 +453,17 @@
    },
    handleRemove(file, fileList) {
      console.log(file, fileList);
      this.fileList = this.fileList.filter((item) => {
        return item.url != file.url;
      });
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
      this.imgArr = [file.url];
      this.previewVisible = true;
    },
    handleSuccess(response, file, fileList) {
      console.log(response, file, fileList);
      this.fileList.push({
        url: process.env.VUE_APP_IMAGE_BASE_URL + response.data,
      });
@@ -456,27 +501,19 @@
      this.$router.push({
        path: "/workList/detail",
        query: {
          projectId: row.projectId,
        },
      });
    },
    toHiddenDanger(row, type) {
      this.$router.push({
        path: "/hiddenDanger",
        query: {
          projectId: row.projectId,
          activeTab: type,
          id: row.id,
        },
      });
    },
    handleSizeChange(val) {
      this.searchParams.pageSize = val;
      this.getlist();
    },
    handleCurrentChange(val) {
      this.searchParams.pageNum = val;
      this.getlist();
    },
    handleClick(type) {
@@ -490,16 +527,6 @@
};
</script>
<style scoped lang="less">
// <div
//   class="flex a-center flex-column gap--15 px--20 py--20 border1 br--8 uploadBox"
// >
//   <img
//     src="../../assets/img/home/89Combined Shape@2x.png"
//     class="w--18 h--18"
//   />
//   <div class="c-fff fs--16">上传图片</div>
// </div>
::v-deep .el-upload--picture-card {
  border: 2px dashed #8c939d;
  background-color: transparent;
@@ -631,20 +658,16 @@
  }
  .btn {
    position: absolute;
    top: -2px;
    right: -2px;
    background: linear-gradient(
      90deg,
      #3467d0 0%,
      #0d226a 50.35%,
      #376fe0 100%
    );
    height: 38px;
    display: flex;
    align-items: center;
    line-height: 38px;
    font-size: 14px;
    color: #ffffff;
    font-family: "Source Han Sans CN Heavy";
    padding: 0 26px;
    border: 1px solid #307ad9;
    box-sizing: border-box;
screen/src/view/workList/service.js
@@ -12,4 +12,30 @@
    method: 'post',
    data
  })
}
export const updateWorkPresentation = async (data) => {
  return request(`/work-presentation/updateWorkPresentation`, {
    method: 'post',
    data
  })
}
export const getWorkPresentationDetail = async (id) => {
  return request(`/work-presentation/getWorkPresentationDetail/${id}`, {
    method: 'get',
  })
}
export const deleteWorkPresentation = async (id) => {
  return request(`/work-presentation/deleteWorkPresentation/${id}`, {
    method: 'delete',
  })
}
export const operateWorkPresentation = async (params) => {
  return request(`/work-presentation/operateWorkPresentation`, {
    method: 'post',
    params
  })
}