Browse Source

Merge remote-tracking branch 'origin/dev' into dev

xuwenhao 8 months ago
parent
commit
3442ae2df2

+ 1 - 1
web/.env.development

@@ -3,7 +3,7 @@ VITE_CLI_PORT = 8080
 VITE_SERVER_PORT = 8888
 VITE_BASE_API = /api
 VITE_FILE_API = /api
-VITE_BASE_PATH = http://127.0.0.1
+VITE_BASE_PATH = http://192.168.110.116
 VITE_POSITION = close
 VITE_EDITOR = vscode
 // VITE_EDITOR = webstorm 如果使用webstorm开发且要使用dom定位到代码行功能 请先自定添加 webstorm到环境变量 再将VITE_EDITOR值修改为webstorm

+ 2 - 0
web/package.json

@@ -24,8 +24,10 @@
         "highlight.js": "^11.8.0",
         "js-cookie": "^3.0.5",
         "jsencrypt": "^3.3.2",
+        "less": "^4.2.0",
         "marked": "4.3.0",
         "mitt": "^3.0.1",
+        "moment": "^2.30.1",
         "nprogress": "^0.2.0",
         "path": "^0.12.7",
         "pinia": "^2.1.4",

+ 41 - 0
web/src/api/project.js

@@ -0,0 +1,41 @@
+import service from '@/utils/request'
+// 获取项目列表
+export const getProjectList = (data) => {
+  return service({
+    url: '/project/queryProjectList',
+    method: 'post',
+    data: data
+    // headers: {
+    //   'Authorization': localStorage.getItem('token')
+    // }
+  })
+}
+
+// 项目立项
+export const createProject = (data) => {
+  return service({
+    url: '/project/createProject',
+    method: 'post',
+    data: data,
+  })
+}
+
+// 项目数据总览
+export const projectDataScreen = () => {
+  return service({
+    url: '/project/queryProjectsInfo',
+    method: 'GET'
+  })
+}
+
+// 获取项目信息
+export const getProjectMessage = (code) => {
+  return service({
+    url: '/project/queryProjectByCode',
+    method: 'GET',
+    params: {
+      code: code
+    }
+  })
+}
+

+ 1 - 1
web/src/api/user.js

@@ -177,4 +177,4 @@ export const getAllUsers = () => {
     url: '/user/queryAllUsers',
     method: 'get'
   })
-}
+}

BIN
web/src/assets/sign.png


+ 307 - 0
web/src/view/projectManage/projectApproval/projectApproval.vue

@@ -0,0 +1,307 @@
+<template>
+  <div>
+    <div
+      style="height: 300px"
+      class="bg-white"
+    >
+      <div class="basicInformation">
+        <div style="padding-top: 10px;margin-left: 90px">
+          <el-image :src="sign" />
+        </div>
+        <div style="display: flex;align-items: center">
+          <el-text
+            style="margin-left: 10px"
+            size="large"
+            tag="b"
+          >项目基本信息</el-text>
+        </div>
+      </div>
+      <el-form>
+        <el-row
+          style="margin:20px 0 0 90px;height: 50px"
+          align="middle"
+        >
+          <el-col :span="5">
+            <el-form-item
+              label="项目名称:"
+              size="large"
+              prop="name"
+            >
+              <el-input
+                v-model="basicMessage.name"
+                placeholder="请输入项目名称"
+                size="large"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col
+            :span="5"
+            :offset="2"
+          >
+            <el-form-item
+              label="负责人:"
+              size="large"
+              prop="principal"
+            >
+              <el-select
+                v-model="basicMessage.principal"
+                placeholder="请选择负责人"
+                @change="headSelect"
+              >
+                <el-option
+                  v-for="item in userList"
+                  :key="item.ID"
+                  :label="item.nickName"
+                  :value="item.nickName"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col
+            :span="5"
+            :offset="2"
+          >
+            <el-form-item
+              label="相关客户:"
+              size="large"
+              prop="customer"
+            >
+              <el-input
+                v-model="basicMessage.customer"
+                placeholder="请输入项目相关客户"
+                size="large"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row
+          style="margin:20px 0 0 90px;height: 50px"
+          align="middle"
+        >
+          <el-col :span="5">
+            <el-form-item
+              label="紧急程度:"
+              size="large"
+            >
+              <el-radio-group
+                v-model="basicMessage.level"
+                @change="changeUrgency"
+              >
+                <el-radio :value="1">正常</el-radio>
+                <el-radio :value="2">重要</el-radio>
+                <el-radio :value="3">紧急</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col
+            :span="6"
+            :offset="2"
+          >
+            <el-form-item
+              label="项目金额:"
+              size="large"
+            >
+              <el-input
+                v-model="projectAmount"
+                style="max-width: 600px"
+                placeholder="请输入项目的具体金额"
+                class="input-with-select"
+              >
+                <template #append>
+                  <el-select
+                    v-model="amountUnit"
+                    placeholder="元"
+                    style="width: 100px"
+                  >
+                    <el-option
+                      label="元"
+                      :value="1"
+                    />
+                    <el-option
+                      label="万元"
+                      :value="2"
+                    />
+                  </el-select>
+                </template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row
+          style="margin:20px 0 0 90px;height: 70px"
+        >
+          <el-col :span="19">
+            <el-form-item
+              label="项目说明:"
+              size="large"
+            >
+              <el-input
+                v-model="basicMessage.illustrate"
+                type="textarea"
+                placeholder="项目说明"
+                :rows="3"
+                size="large"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+    <div
+      style="height: 400px;margin-top: 20px"
+      class="bg-white"
+    >
+      <div class="basicInformation">
+        <div style="padding-top: 10px;margin-left: 90px">
+          <el-image :src="sign" />
+        </div>
+        <div style="display: flex;align-items: center">
+          <el-text
+            style="margin-left: 10px"
+            size="large"
+            tag="b"
+          >项目附属文件</el-text>
+        </div>
+      </div>
+      <el-row style="margin:20px 0 0 90px;">
+        <el-col :span="15">
+          <el-upload
+            class="upload-demo"
+            drag
+            multiple
+            :auto-upload="false"
+            :file-list="fileListData"
+            :on-change="changeFileData"
+            :on-remove="removeFileData"
+          >
+            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+            <div class="el-upload__text">
+              请选择需要上传的文件
+            </div>
+            <template #tip>
+              <div class="el-upload__tip">
+                选择的文件不要超过500MB
+              </div>
+            </template>
+          </el-upload>
+        </el-col>
+        <el-col
+          :span="4"
+          :offset="1"
+        >
+          <el-button
+            icon="Collection"
+            size="large"
+            type="primary"
+            @click="approval"
+          >项目立项</el-button>
+        </el-col>
+      </el-row>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue'
+import sign from '@/assets/sign.png'
+import moment from 'moment/moment'
+import { createProject } from '@/api/project'
+import { getAllUsers } from '@/api/user'
+import { ElMessage } from 'element-plus'
+defineOptions({
+  name: 'ProjectApproval'
+})
+// 表单验证规则
+// const fromRules = {
+//   name: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
+//   principal: [{ required: true, message: '项目负责人不能为空', trigger: 'blur' }],
+//   customer: [{ required: true, message: '项目相关用户不能为空', trigger: 'blur' }]
+// }
+// 项目基本信息
+const basicMessage = reactive({
+  code: '',
+  name: '智慧路口',
+  principal: '',
+  price: 0,
+  level: 1,
+  customer: '交通局',
+  illustrate: '智慧路口项目',
+  progress: 0,
+  state: 1
+})
+const projectAmount = ref('')
+// 项目用户列表
+const userList = reactive([])
+getAllUsers().then(res => {
+  if (res.code === 0) {
+    userList.push(...res.data)
+  }
+})
+// 项目文件列表
+const fileListData = ref([])
+// 金额单位
+const amountUnit = ref('元')
+// 修改负责人
+const headSelect = (value) => {
+  basicMessage.principal = value
+}
+// 修改文件数据
+const changeFileData = (file, fileList) => {
+  fileListData.value = fileList
+  console.log(fileListData)
+}
+const removeFileData = (file, fileList) => {
+  fileListData.value = fileList
+  console.log(fileListData)
+}
+// 项目紧急程度
+function changeUrgency(value) {
+  basicMessage.level = value
+}
+// 项目立项
+const approval = () => {
+  if (fileListData.value.length === 0) {
+    return ElMessage.warning('请选取文件后再上传')
+  }
+  const basic = basicMessage
+  basic.code = 'LCZM' + createCode()
+  if (amountUnit.value === '万元') {
+    basic.price = parseInt(projectAmount.value) * 10000
+  } else {
+    basic.price = parseInt(projectAmount.value)
+  }
+  const formData = new FormData()
+  const json = JSON.stringify(basic)
+  fileListData.value.forEach(item => {
+    formData.append('file', item.raw)
+  })
+  formData.append('project', json)
+  createProject(formData).then(res => {
+    console.log(res)
+    if (res.code === 0) {
+      ElMessage({
+        message: '立项成功',
+        type: 'success',
+      })
+    } else {
+      ElMessage({
+        message: '立项失败',
+        type: 'error',
+      })
+    }
+  })
+}
+
+const createCode = () => {
+  return moment().format('YYYYMMDDHHmm')
+}
+</script>
+
+<style scoped lang="less">
+.basicInformation{
+  height: 40px;
+  background-color: #f8fafd;
+  display: flex;
+  //align-items: center;
+}
+</style>

+ 21 - 0
web/src/view/projectManage/projectDetails/projectDetails.vue

@@ -0,0 +1,21 @@
+<template>
+  <div>
+    <div class="w-20 h-20 bg-white">
+      项目详情
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { getProjectMessage } from '@/api/project'
+defineOptions({
+  name: 'projectDetails'
+})
+getProjectMessage().then(res => {
+  console.log(res)
+})
+</script>
+
+<style scoped>
+
+</style>

+ 308 - 0
web/src/view/projectManage/projectList/projectList.vue

@@ -0,0 +1,308 @@
+<template>
+  <div>
+    <el-row>
+      <el-col :span="4">
+        <el-form-item label="项目名称">
+          <el-input placeholder="请输入项目名称" />
+        </el-form-item>
+      </el-col>
+      <el-col
+        :span="4"
+        :offset="1"
+      >
+        <el-form-item label="立项时间">
+          <el-date-picker
+            v-model="approvalTime"
+            type="month"
+            placeholder="请选择立项时间"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col
+        :span="4"
+        :offset="1"
+      >
+        <el-form-item label="项目状态">
+          <el-select />
+        </el-form-item>
+      </el-col>
+      <el-col
+        :span="2"
+        :offset="1"
+      >
+        <el-button
+          type="primary"
+          :icon="Search"
+          @click="initializedData"
+        >查询</el-button>
+      </el-col>
+      <el-col
+        :span="2"
+      >
+        <el-button
+          type="primary"
+          :icon="DocumentCopy"
+          @click="initializedData"
+        >立项</el-button>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="23">
+        <el-row justify="space-between">
+          <el-col :span="5">
+            <div class="bg-white h-24">
+              <el-row
+                style="height: 40%"
+                align="middle"
+              >
+                <el-col :offset="2">
+                  <el-text
+                    style="font-family: 黑体;"
+                  >项目总数</el-text>
+                </el-col>
+              </el-row>
+              <el-row
+                style="height: 60%"
+                align="middle"
+              >
+                <el-col :offset="2">
+                  <span class="dataStyle">{{ screenData.totalProject }}</span>
+                </el-col>
+              </el-row>
+            </div>
+          </el-col>
+          <el-col :span="5">
+            <div class="bg-white h-24">
+              <el-row
+                  style="height: 40%"
+                  align="middle"
+              >
+                <el-col :offset="2">
+                  <el-text
+                      style="font-family: 黑体;"
+                  >执行中项目</el-text>
+                </el-col>
+              </el-row>
+              <el-row
+                  style="height: 60%"
+                  align="middle"
+              >
+                <el-col :offset="2">
+                  <span class="dataStyle">{{ screenData.unCompleteProject }}</span>
+                </el-col>
+              </el-row>
+            </div>
+          </el-col>
+          <el-col :span="5">
+            <div class="bg-white h-24">
+              <el-row
+                  style="height: 40%"
+                  align="middle"
+              >
+                <el-col :offset="2">
+                  <el-text
+                      style="font-family: 黑体;"
+                  >已完成项目</el-text>
+                </el-col>
+              </el-row>
+              <el-row
+                  style="height: 60%"
+                  align="middle"
+              >
+                <el-col :offset="2">
+                  <span class="dataStyle">{{ screenData.completeProject }}</span>
+                </el-col>
+              </el-row>
+            </div>
+          </el-col>
+          <el-col :span="5">
+            <div class="bg-white h-24">
+              <el-row
+                  style="height: 40%"
+                  align="middle"
+              >
+                <el-col :offset="2">
+                  <el-text
+                      style="font-family: 黑体;"
+                  >项目总金额</el-text>
+                </el-col>
+              </el-row>
+              <el-row
+                  style="height: 60%"
+                  align="middle"
+              >
+                <el-col :offset="2">
+                  <span class="dataStyle">{{ screenData.sum }}元</span>
+                </el-col>
+              </el-row>
+            </div>
+          </el-col>
+        </el-row>
+      </el-col>
+    </el-row>
+    <el-form>
+      <el-row style="margin-top: 20px;">
+        <el-col
+          :span="23"
+        >
+          <el-table
+            :data="projectListData"
+            height="580"
+          >
+            <el-table-column
+              prop="code"
+              label="项目编码"
+              align="center"
+            />
+            <el-table-column
+              prop="name"
+              label="项目名称"
+              align="center"
+            />
+            <el-table-column
+              prop="principal"
+              label="项目负责人"
+              align="center"
+            />
+            <el-table-column
+              prop="price"
+              label="项目金额"
+              align="center"
+            />
+            <el-table-column
+              prop="CreatedAt"
+              label="立项日期"
+              align="center"
+            />
+            <el-table-column
+              prop="state"
+              label="状态"
+              align="center"
+            />
+            <el-table-column
+              label="项目操作"
+              align="center"
+            >
+              <template #default="scope">
+                <el-button
+                  size="small"
+                  @click="projectEdit(scope.$index, scope.row)"
+                >
+                  详情
+                </el-button>
+                <el-button
+                  size="small"
+                  type="danger"
+                  @click="projectDelete(scope.$index, scope.row)"
+                >
+                  删除
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-col>
+      </el-row>
+    </el-form>
+    <el-row>
+      <el-col
+        :span="23"
+        style="display: flex;justify-content: end"
+      >
+        <el-pagination
+          :page-size="10"
+          background
+          layout="prev, pager, next"
+          :total="listTotal"
+          @change="changePage"
+        />
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { DocumentCopy, Search } from '@element-plus/icons-vue'
+import { getProjectList, projectDataScreen } from '@/api/project'
+import { reactive, ref, onMounted } from 'vue'
+
+defineOptions({
+  name: 'ProjectList'
+})
+const screenData = reactive({})
+const approvalTime = ref('')
+const projectListData = reactive([])
+const listTotal = ref(0)
+const data = {
+  pageInfo: {
+    page: 1,
+    pageSize: 10
+  },
+  name: '',
+  time: '',
+  state: 0
+}
+const projectEdit = (index, row) => {
+}
+const projectDelete = (index, row) => {
+}
+// 项目数据总览
+onMounted(() => {
+  projectDataScreen().then(res => {
+    console.log(res.data)
+    const obj = res.data
+    Object.keys(obj).forEach(key => {
+      screenData[key] = obj[key]
+    })
+  })
+  // 获取项目列表
+  getProjectList(data).then(res => {
+    if (res.code === 0 && res.data.total > 0) {
+      const list = res.data.list
+      list.forEach(item => {
+        item.CreatedAt = formatDate(item.CreatedAt)
+        item.state = projectState(item.state)
+      })
+      projectListData.push(...list)
+      listTotal.value = res.data.total
+    }
+  })
+})
+function formatDate(dateString, locale = 'en-US', timezone = 'Asia/Shanghai') {
+  // 使用 Date 构造函数解析日期字符串
+  const date = new Date(dateString)
+
+  // 检查日期是否有效
+  if (isNaN(date.getTime())) {
+    throw new Error('Invalid date string')
+  }
+
+  // 使用 Date 对象的年份、月份和日期来构建新的日期字符串
+  // 注意:JavaScript 中的月份是从 0 开始的,所以我们需要加 1
+  const formattedDate = `${date.getFullYear()}-${('0' + (date.getMonth() + 1)).slice(-2)}-${('0' + date.getDate()).slice(-2)}`
+
+  return formattedDate
+}
+const projectState = (state) => {
+  const obj = {
+    1: '立项',
+    2: '施工',
+    3: '收款',
+    4: '完成',
+    5: '失效'
+  }
+  return obj[state]
+}
+const initializedData = () => {
+  console.log(screenData.totalProject)
+}
+const changePage = (value) => {
+  console.log(value)
+}
+</script>
+
+<style scoped lang="less">
+  .dataStyle{
+    font-size: 25px;
+    font-weight: 500;
+  }
+</style>