-
admin
2025-01-03 436fde61ac5231dd3cc79a7951ad7897f751fc77
-
已添加9个文件
567 ■■■■■ 文件已修改
api/dema/dictData.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/dema/projectInfo.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/dema/workHourInfo.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/ProjectSelector/index.vue 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/common/hideheadUtils.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/common/selectProject/index.vue 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/dema/banner1.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/dema/banner2.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/dema/banner3.jpg 补丁 | 查看 | 原始文档 | blame | 历史
api/dema/dictData.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
import request from '@/utils/request'
// æŸ¥è¯¢å­—典数据列表
export function listData(query) {
  return request({
    url: '/system/dict/data/list',
    method: 'get',
    params: query
  })
}
// æŸ¥è¯¢å­—典数据详细
export function getData(dictCode) {
  return request({
    url: '/system/dict/data/' + dictCode,
    method: 'get'
  })
}
// æ ¹æ®å­—典类型查询字典数据信息
export function getDicts(dictType) {
  return request({
    url: '/system/dict/data/type/' + dictType,
    method: 'get'
  })
}
// æ–°å¢žå­—典数据
export function addData(data) {
  return request({
    url: '/system/dict/data',
    method: 'post',
    data: data
  })
}
// ä¿®æ”¹å­—典数据
export function updateData(data) {
  return request({
    url: '/system/dict/data',
    method: 'put',
    data: data
  })
}
// åˆ é™¤å­—典数据
export function delData(dictCode) {
  return request({
    url: '/system/dict/data/' + dictCode,
    method: 'delete'
  })
}
api/dema/projectInfo.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
import request from '@/utils/request'
// æŸ¥è¯¢é¡¹ç›®ä¿¡æ¯åˆ—表
export function listProjectInfo(query) {
  return request({
    url: '/bs/projectInfo/list',
    method: 'get',
    params: query
  })
}
// æŸ¥è¯¢é¡¹ç›®ä¿¡æ¯åˆ—表
export function listProjectInfoNoPage(query) {
  return request({
    url: '/bs/projectInfo/listNoPage',
    method: 'get',
    params: query
  })
}
// æŸ¥è¯¢é¡¹ç›®ä¿¡æ¯è¯¦ç»†
export function getProjectInfo(projectId) {
  return request({
    url: '/bs/projectInfo/' + projectId,
    method: 'get'
  })
}
// æ–°å¢žé¡¹ç›®ä¿¡æ¯
export function addProjectInfo(data) {
  return request({
    url: '/bs/projectInfo',
    method: 'post',
    data: data
  })
}
// ä¿®æ”¹é¡¹ç›®ä¿¡æ¯
export function updateProjectInfo(data) {
  return request({
    url: '/bs/projectInfo',
    method: 'put',
    data: data
  })
}
// åˆ é™¤é¡¹ç›®ä¿¡æ¯
export function delProjectInfo(projectId) {
  return request({
    url: '/bs/projectInfo/' + projectId,
    method: 'delete'
  })
}
api/dema/workHourInfo.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
import request from '@/utils/request'
// æŸ¥è¯¢å·¥æ—¶æ˜Žç»†åˆ—表
export function listWorkHourInfo(query) {
  return request({
    url: '/am/workHourInfo/list',
    method: 'get',
    params: query
  })
}
export function listWorkHourInfoNoPage(query) {
  return request({
    url: '/am/workHourInfo/listNoPage',
    method: 'get',
    params: query
  })
}
export function listWorkHourInfoCommon(query) {
  return request({
    url: '/am/workHourInfoCommon/listWorkHourInfoCommon',
    method: 'get',
    params: query
  })
}
// æŸ¥è¯¢å·¥æ—¶æ˜Žç»†è¯¦ç»†
export function getWorkHourInfo(workHourId) {
  return request({
    url: '/am/workHourInfo/' + workHourId,
    method: 'get'
  })
}
// æ–°å¢žå·¥æ—¶æ˜Žç»†
export function appAddWorkHourInfo(data) {
  return request({
    url: '/am/workHourInfo/appAdd',
    method: 'post',
    data: data
  })
}
// ä¿®æ”¹å·¥æ—¶æ˜Žç»†
export function appUpdateWorkHourInfo(data) {
  return request({
    url: '/am/workHourInfo/appUpdate',
    method: 'put',
    data: data
  })
}
// åˆ é™¤å·¥æ—¶æ˜Žç»†
export function delWorkHourInfo(workHourId) {
  return request({
    url: '/am/workHourInfo/' + workHourId,
    method: 'delete'
  })
}
components/ProjectSelector/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,194 @@
<template>
  <uni-popup
    ref="popup"
    type="bottom"
    @change="onPopupChange"
  >
    <view class="popup-content">
      <view class="popup-header">
        <text class="popup-title">选择项目</text>
        <text class="popup-close" @click="handleClose">×</text>
      </view>
      <!-- æ·»åŠ æœç´¢æ¡† -->
      <view class="popup-search">
        <uni-easyinput
          v-model="searchKeyword"
          placeholder="搜索项目"
          prefixIcon="search"
        />
      </view>
      <scroll-view scroll-y class="popup-list">
        <!-- æ·»åŠ åŠ è½½çŠ¶æ€æ˜¾ç¤º -->
        <view v-if="loading" class="loading-container">
          <uni-load-more status="loading" :content-text="loadingText"></uni-load-more>
        </view>
        <!-- æ·»åŠ ç©ºçŠ¶æ€æ˜¾ç¤º -->
        <view v-else-if="!projectList.length" class="empty-container">
          <text class="empty-text">暂无项目数据</text>
        </view>
        <!-- é¡¹ç›®åˆ—表 -->
        <template v-else>
          <view
            class="popup-item"
            v-for="item in filteredProjects"
            :key="item.value"
            @click="handleConfirm(item)"
          >
            {{ item.text }}
          </view>
        </template>
      </scroll-view>
    </view>
  </uni-popup>
</template>
<style>
.popup-content {
  background-color: #fff;
  border-radius: 16px 16px 0 0;
  padding: 20px;
}
.popup-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}
.popup-title {
  font-size: 16px;
  font-weight: bold;
}
.popup-close {
  font-size: 20px;
  color: #666;
  padding: 0 10px;
  cursor: pointer;
}
.popup-search {
  padding: 10px 0;
  border-bottom: 1px solid #ebeef5;
}
.popup-list {
  margin-top: 10px;
  max-height: 40vh;
}
.popup-item {
  padding: 12px 15px;
  border-bottom: 1px solid #ebeef5;
  transition: all 0.3s;
}
.popup-item:hover {
  background-color: #f5f7fa;
}
.popup-item:active {
  background-color: #e8f4ff;
}
:deep(.uni-easyinput__content) {
  background-color: #f5f5f5;
  border-radius: 4px;
}
/* æ·»åŠ åŠ è½½çŠ¶æ€å’Œç©ºçŠ¶æ€æ ·å¼ */
.loading-container,
.empty-container {
  padding: 20px 0;
  display: flex;
  justify-content: center;
  align-items: center;
}
.empty-text {
  color: #909399;
  font-size: 14px;
}
</style>
<script>
import { listProjectInfoNoPage } from '@/api/dema/projectInfo.js'
export default {
  name: 'ProjectSelector',
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      loadingText: '',
      searchKeyword: '',
      selectedValue: '',
      projectList: [],
      loading: false,
    }
  },
  computed: {
    filteredProjects() {
      if (!this.searchKeyword) return this.projectList;
      const keyword = this.searchKeyword.toLowerCase();
      return this.projectList.filter(item =>
        item.text.toLowerCase().includes(keyword) ||
        item.value.toLowerCase().includes(keyword)
      );
    }
  },
  created() {
    // ç»„件创建时加载项目列表
    this.getProjectList();
  },
  methods: {
    // èŽ·å–项目列表
    async getProjectList() {
      try {
        this.loading = true;
        const response = await listProjectInfoNoPage();
        if (response && response.rows) {
          // è½¬æ¢API返回的数据格式
          this.projectList = response.rows.map(item => ({
            value: item.projectCode,
            text: item.projectName
          }));
        }
      } catch (error) {
        console.error('获取项目列表失败:', error);
        this.$modal.msgError('获取项目列表失败');
      } finally {
        this.loading = false;
      }
    },
    show() {
      // æ¯æ¬¡æ˜¾ç¤ºæ—¶åˆ·æ–°é¡¹ç›®åˆ—表
      this.getProjectList();
      this.$refs.popup.open();
    },
    handleClose() {
      this.$refs.popup.close();
      this.searchKeyword = '';
    },
    handleConfirm(item) {
      this.$emit('input', item.value);
      this.$emit('change', {
        value: item.value,
        text: item.text,
      });
      this.handleClose();
    },
    onPopupChange(e) {
      if (!e.show) {
        this.searchKeyword = '';
      }
    }
  }
}
</script>
pages/common/hideheadUtils.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
import * as dd from 'dingtalk-jsapi';
import {ddlogin} from "@/api/login";
export function ddReady() {
  return new Promise((resolve, reject) => {
    var corpId = 'dingb6bf7fe744b1273835c2f4657eb6378f';
    // ä½¿ç”¨SDK èŽ·å–免登授权码
    dd.runtime.permission.requestAuthCode({
      corpId: corpId,
      onSuccess: function (result) {
        var code = result.code;
        sessionStorage.setItem('code', code);
        ddlogin({ authCode: code }).then(res => {
          if (res.code === 200) {
            resolve(res.data); // è¿”回数据
          } else {
            reject(new Error('登录失败')); // å¤„理错误
          }
        }).catch(error => {
          reject(error); // å¤„理 ddlogin çš„错误
        });
      },
      onFail: function (err) {
        reject(err); // å¤„理 requestAuthCode çš„错误
      }
    });
  });
}
export default {
  dd
}
pages/common/selectProject/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,177 @@
<template>
  <view class="project-selector">
    <uni-popup ref="popup" type="center">
      <view class="popup-content">
        <view class="popup-header">
          <text class="title">选择项目</text>
          <text class="close" @click="handleClose">×</text>
        </view>
        <view class="search-box">
          <uni-easyinput
            v-model="searchKeyword"
            placeholder="搜索项目"
            prefixIcon="search"
            @input="handleSearch"
          />
        </view>
        <view class="list-container">
          <uni-list>
            <uni-list-item v-for="item in filteredProjectList" :key="item.value">
              <template v-slot:header>
                <radio-group @change="handleRadioChange">
                  <radio :value="item.value" :checked="selectedValue === item.value" />
                </radio-group>
              </template>
              <template v-slot:body>
                <text class="project-text">{{ item.text }}</text>
              </template>
            </uni-list-item>
          </uni-list>
        </view>
        <view class="popup-footer">
          <button type="primary" @click="handleConfirm">确定</button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>
<script>
export default {
  name: 'ProjectSelector',
  props: {
    value: {
      type: [String, Number],
      default: ''
    }
  },
  data() {
    return {
      selectedValue: '',
      searchKeyword: '',
      projectList: [
        { value: '0', text: "042湖州智芯" },
        { value: '1', text: "040春风动力" },
      ]
    }
  },
  computed: {
    filteredProjectList() {
      if (!this.searchKeyword) return this.projectList;
      return this.projectList.filter(item =>
        item.text.toLowerCase().includes(this.searchKeyword.toLowerCase())
      );
    }
  },
  created() {
    this.selectedValue = this.value
  },
  methods: {
    show() {
      this.$refs.popup.open()
    },
    handleClose() {
      this.$refs.popup.close()
      this.searchKeyword = ''
    },
    handleRadioChange(e) {
      this.selectedValue = e.detail.value
    },
    handleConfirm() {
      const selectedProject = this.projectList.find(item => item.value === this.selectedValue)
      this.$emit('input', this.selectedValue)
      this.$emit('change', selectedProject)
      if (selectedProject) {
          this.$emit('input', this.selectedValue)
          this.$emit('change', {
            value: selectedProject.value,
            text: selectedProject.text,
          })
        }
      this.handleClose()
    },
    handleSearch(value) {
      this.searchKeyword = value
    }
  }
}
</script>
<style>
.project-selector {
  width: 100%;
}
.popup-content {
  background-color: #fff;
  width: 90vw;
  border-radius: 10px;
  padding: 10px;
}
.popup-header {
  padding: 2px;
  border-bottom: 1px solid #eee;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.title {
  font-size: 16px;
  font-weight: bold;
}
.close {
  font-size: 20px;
  color: #666;
  padding: 0 10px;
  cursor: pointer;
}
.search-box {
  padding: 10px;
  border-bottom: 1px solid #eee;
}
.list-container {
  max-height: 60vh;
  overflow-y: auto;
  padding: 10px 0;
}
.project-text {
  margin-left: 10px;
  font-size: 14px;
}
.popup-footer {
  padding: 15px;
  border-top: 1px solid #eee;
  display: flex;
  justify-content: flex-end;
}
.popup-footer button {
  min-width: 100px;
}
radio-group {
  margin-right: 10px;
}
:deep(.uni-list-item) {
  padding: 8px 0;
}
:deep(.uni-list-item__container) {
  padding: 8px 15px;
}
:deep(.uni-easyinput__content) {
  background-color: #f5f5f5;
  border-radius: 4px;
}
</style>
static/dema/banner1.jpg
static/dema/banner2.jpg
static/dema/banner3.jpg