Преглед изворни кода

项目跟踪前端页面搭建

songxy пре 10 месеци
родитељ
комит
09e7d63cdf

+ 8 - 0
client/src/router/modules/remaining.ts

@@ -241,6 +241,14 @@ const remainingRouter: AppRouteRecordRaw[] = [
           title: '学习中心详情'
         }
       },
+      {
+        path: 'projectTrack',
+        component: () => import('@/views/OaSystem/projectCenter/projectTrack/index.vue'),
+        name: 'ProjectTrack',
+        meta: {
+          title: '项目跟踪'
+        }
+      },
       {
         path: 'projectDetail',
         component: () => import('@/views/OaSystem/projectCenter/projectDetail/projectDetail.vue'),

+ 86 - 0
client/src/views/OaSystem/projectCenter/projectTrack/common.ts

@@ -0,0 +1,86 @@
+import moment from 'moment'
+import download from '@/utils/download'
+
+interface QueryParam {
+  xmbh: string
+  xmmc: string
+  xmlbId: string
+  lxsjOn: string
+  lxsjOff: string
+  pageNo: number
+  xzqdm: number | string
+  pageSize: number
+  isSign: any
+  xmzt: any
+  xmjlId: string
+  hyId: any
+}
+export const useMixins = () => {
+  const queryParams = reactive<QueryParam>({
+    xmbh: '',
+    xmmc: '',
+    xmlbId: '15',
+    lxsjOn: '',
+    lxsjOff: '',
+    pageNo: 1,
+    xzqdm: '',
+    pageSize: 15,
+    isSign: '',
+    xmzt: '',
+    xmjlId: '',
+    hyId: 0
+  })
+  const lxsjObj = ref()
+  const setSearchParams = (): void => {
+    if (lxsjObj.value && lxsjObj.value.length > 0) {
+      queryParams.lxsjOn = moment(lxsjObj.value[0]).format('YYYY-MM-DD')
+      queryParams.lxsjOff = moment(lxsjObj.value[1]).format('YYYY-MM-DD')
+    } else {
+      queryParams.lxsjOn = ''
+      queryParams.lxsjOff = ''
+    }
+    if (queryParams.hyId == 0) {
+      queryParams.hyId = null
+    }
+  }
+  const exportHandleCommon = (request, params, fileName: string): void => {
+    if (lxsjObj.value && lxsjObj.value.length > 0) {
+      queryParams.lxsjOn = moment(lxsjObj.value[0]).format('YYYY-MM-DD')
+      queryParams.lxsjOff = moment(lxsjObj.value[1]).format('YYYY-MM-DD')
+    } else {
+      queryParams.lxsjOn = ''
+      queryParams.lxsjOff = ''
+    }
+    if (queryParams.hyId == 0) {
+      queryParams.hyId = null
+    }
+    const urlApi = `/project/list/excel`
+    setSearchParams()
+    const sendData = {
+      ...queryParams,
+      ...params
+    }
+    request.download({ url: urlApi, params: sendData }, '/business').then((blob) => {
+      download.excel(blob, fileName)
+    })
+  }
+  return {
+    queryParams,
+    lxsjObj,
+    setSearchParams,
+    exportHandleCommon
+  }
+}
+
+export const infoList: any = reactive([
+  {
+    icon: 'xmzx/xmzcz',
+    name: '项目总金额',
+    num: 0
+  },
+  {
+    icon: 'xmzx/xmzlr',
+    name: '项目总个数',
+    num: 0
+  }
+])

+ 275 - 0
client/src/views/OaSystem/projectCenter/projectTrack/index.vue

@@ -0,0 +1,275 @@
+<template>
+  <div class="oa-sys-list-view">
+    <div class="searchBox">
+      <div class="form">
+        <span class="formSpan">年份:</span>
+        <el-input v-model="queryParams.xmbh" placeholder="请输入项目编号" style="width: 160px" />
+      </div>
+      <div class="form">
+        <span class="formSpan">项目名称:</span>
+        <el-input v-model="queryParams.xmmc" placeholder="请输入项目名称" style="width: 210px" />
+      </div>
+      <div class="form">
+        <span class="formSpan">项目部门:</span>
+        <DeptTree v-model="queryParams['deptId']" placeholder="请选择部门" />
+      </div>
+      <div class="form">
+        <span class="formSpan">跟踪人员:</span>
+        <UserOrgTree v-model="queryParams['xmjlId']" :all="true" placeholder="请选择项目经理" />
+      </div>
+      <div class="from">
+        <div class="btnBox">
+          <el-button type="primary" style="background: #3485ff" @click="searchHandle">
+            <img src="@/assets/imgs/OA/search.png" class="mr-8px" alt="" />
+            查询</el-button
+          >
+          <el-button type="primary" @click="addHandle">
+            <img src="@/assets/imgs/OA/open.png" class="mr-8px" alt="" />
+            新增</el-button
+          >
+        </div>
+      </div>
+    </div>
+    <div class="infoBox">
+      <ul>
+        <li v-for="(item, index) in infoList" :key="index" class="mr-40px">
+          <img class="mr-8px" :src="getAssetURL(item.icon)" alt="" />
+          <p>{{ item.name }}:</p>
+          <h4 class="font-size-18px" v-money:unit="item.num"></h4>
+        </li>
+      </ul>
+    </div>
+    <div class="tableBox">
+      <div class="table" ref="tableRef">
+        <el-table
+          stripe
+          :data="tableData"
+          style="width: 100%; height: 100%"
+          :style="{ height: tableHeight + 'px' }"
+          :header-cell-style="{
+            background: '#E5F0FB',
+            color: '#233755',
+            height: '50px'
+          }"
+        >
+          <el-table-column label="序号" width="80">
+            <template #default="scope">{{ scope.$index + 1 }}</template>
+          </el-table-column>
+          <el-table-column
+            :show-overflow-tooltip="true"
+            prop="xmmc"
+            label="项目名称"
+            :min-width="250"
+          />
+          <el-table-column prop="lxsj" label="跟踪人员" width="140" />
+          <el-table-column
+            prop="zrbm"
+            label="预估金额(万元)"
+            :show-overflow-tooltip="true"
+            width="200"
+          />
+          <el-table-column prop="xmjl" label="甲方" width="120" />
+          <el-table-column prop="xmjl" label="甲方对接人" width="120" />
+          <el-table-column prop="xmjl" label="项目归属部门" width="120" />
+          <el-table-column prop="xmjl" label="行政区" width="120" />
+          <el-table-column prop="xmzt" label="项目状态" width="120">
+            <template #default="scope">
+              {{ getDictLabel(DICT_TYPE.PROJECT_STATUS, scope.row.xmzt) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="xmjl" label="开关" width="120" />
+
+          <el-table-column label="操作" width="80" fixed="right">
+            <template #default="scope">
+              <div class="operateBtn" @click="operateClick(scope.row)">
+                <span>查看</span>
+              </div>
+              <div class="operateBtn" @click="operateClick(scope.row)">
+                <span>编辑</span>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div class="pageBox">
+        <el-pagination
+          v-model:current-page="queryParams.pageNo"
+          :page-size="queryParams.pageSize"
+          background
+          layout="total, prev, pager, next, jumper"
+          :total="total"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+    <el-dialog v-model="dialogVisible" title="项目跟踪填报" width="660px" align-center>
+      <el-form
+        ref="ruleFormRef"
+        style="width: 600px"
+        :model="ruleForm"
+        label-width="auto"
+        class="demo-ruleForm"
+        status-icon
+      >
+        <el-form-item label="项目名称" prop="name">
+          <el-input v-model="ruleForm.name" />
+        </el-form-item>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="跟踪人员" prop="region">
+              <el-select v-model="ruleForm.region" placeholder="Activity zone">
+                <el-option label="Zone one" value="shanghai" />
+                <el-option label="Zone two" value="beijing" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="甲方" prop="name">
+              <el-input v-model="ruleForm.name" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="预估金额(万元)" prop="name">
+              <el-input v-model="ruleForm.name" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="甲方对接人" prop="name">
+              <el-input v-model="ruleForm.name" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="项目归属部门" prop="region">
+              <el-select v-model="ruleForm.region" placeholder="Activity zone">
+                <el-option label="Zone one" value="shanghai" />
+                <el-option label="Zone two" value="beijing" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="行政区" prop="region">
+              <el-select v-model="ruleForm.region" placeholder="Activity zone">
+                <el-option label="Zone one" value="shanghai" />
+                <el-option label="Zone two" value="beijing" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="状态" prop="region">
+              <el-select v-model="ruleForm.region" placeholder="Activity zone">
+                <el-option label="Zone one" value="shanghai" />
+                <el-option label="Zone two" value="beijing" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="谁可见" prop="region">
+              <el-select v-model="ruleForm.region" placeholder="Activity zone">
+                <el-option label="Zone one" value="shanghai" />
+                <el-option label="Zone two" value="beijing" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="备注" prop="desc">
+          <el-input v-model="ruleForm.desc" type="textarea" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="dialogVisible = false">关闭</el-button>
+          <el-button type="primary" @click="onSaveHandle"> 保存 </el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup lang="ts">
+import { useRouter } from 'vue-router'
+import { DICT_TYPE, getDictLabel } from '@/utils/dict'
+import { useMixins, infoList } from './common'
+import request from '@/config/axios'
+import { getAssetURL } from '@/utils/auth'
+import UserOrgTree from '@/views/OaSystem/components/UserOrgTree/index.vue'
+import DeptTree from '@/views/OaSystem/components/DeptTree/index.vue'
+
+defineOptions({ name: 'ProjectBook' })
+const router = useRouter()
+const tableRef: any = ref(null)
+const tableHeight: any = ref(0)
+const { queryParams, setSearchParams } = useMixins()
+
+const handleCurrentChange = (pageNo: number) => {
+  queryParams.pageNo = pageNo
+  queryProjectListAjax()
+}
+interface IFormType {}
+const ruleForm = ref<IFormType>({
+  name: ''
+})
+/**
+ * 操作:查看、编辑
+ */
+const dialogVisible = ref<boolean>(false)
+//type 0 查看 1 编辑
+const operateClick = (row: any, type: number = 0) => {
+  dialogVisible.value = true
+}
+/**
+ * 新建项目跟踪
+ */
+const addHandle = () => {
+  dialogVisible.value = true
+}
+const tableData = ref<Array<any>>([])
+const total = ref<number>()
+const searchHandle: () => void = () => {
+  queryProjectCalculate()
+  queryProjectListAjax()
+}
+const queryProjectListAjax = async (): Promise<void> => {
+  const urlApi = `/project/page`
+  setSearchParams()
+  const sendData = {
+    ...queryParams,
+    pageSize: 15
+  }
+  const result = await request.get({ url: urlApi, params: sendData }, '/business')
+  tableData.value = result['records']
+  total.value = result['total']
+}
+queryProjectListAjax()
+
+/**
+ * 获取项目台账金额计算
+ */
+const queryProjectCalculate = async (): Promise<void> => {
+  const urlApi = `/project/calculate`
+  setSearchParams()
+  const sendData = {
+    ...queryParams
+  }
+  const result = await request.get({ url: urlApi, params: sendData }, '/business')
+  if (result) {
+    infoList[0]['num'] = result.output ?? 0
+    infoList[1]['num'] = result.cost ?? 0
+  }
+}
+queryProjectCalculate()
+const onSaveHandle = () => {}
+onMounted(() => {
+  tableHeight.value = tableRef.value.clientHeight
+})
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-radio) {
+  margin-right: 10px;
+}
+</style>