index copy.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. <template>
  2. <div class="oa-sys-list-view">
  3. <div class="searchBox">
  4. <div class="form">
  5. <span class="formSpan">项目名称:</span>
  6. <el-input v-model="queryParams.xmmc" placeholder="请输入项目名称" style="width: 210px" />
  7. </div>
  8. <div class="form">
  9. <span class="formSpan">项目部门:</span>
  10. <DeptTree v-model="queryParams['xmbmId']" placeholder="请选择部门" />
  11. </div>
  12. <div class="form">
  13. <span class="formSpan">跟踪人员:</span>
  14. <UserOrgTree v-model="queryParams['gzryId']" placeholder="请选择跟踪人员" />
  15. </div>
  16. <div class="from">
  17. <div class="btnBox">
  18. <el-button type="primary" style="background: #3485ff" @click="searchHandle">
  19. <img src="@/assets/imgs/OA/search.png" class="mr-8px" alt="" />
  20. 查询</el-button
  21. >
  22. <el-button type="primary" @click="addOrEditHandle()">
  23. <img src="@/assets/imgs/OA/open.png" class="mr-8px" alt="" />
  24. 新增</el-button
  25. >
  26. </div>
  27. </div>
  28. </div>
  29. <div class="infoBox">
  30. <ul>
  31. <li v-for="(item, index) in infoList" :key="index" class="mr-40px">
  32. <img class="mr-8px" :src="getAssetURL(item.icon)" alt="" />
  33. <p>{{ item.name }}:</p>
  34. <h4 class="font-size-18px">{{ item.num.toFixed(0) }}{{ item.unit }}</h4>
  35. </li>
  36. </ul>
  37. </div>
  38. <div class="tableBox">
  39. <div class="table" ref="tableRef">
  40. <el-table
  41. stripe
  42. :data="tableData"
  43. style="width: 100%; height: 100%"
  44. :style="{ height: tableHeight + 'px' }"
  45. :header-cell-style="{
  46. background: '#E5F0FB',
  47. color: '#233755',
  48. height: '50px'
  49. }"
  50. >
  51. <el-table-column label="序号" width="80">
  52. <template #default="scope">{{ scope.$index + 1 }}</template>
  53. </el-table-column>
  54. <el-table-column prop="zt" label="状态" width="120">
  55. <template #default="scope">
  56. {{ getDictLabel(DICT_TYPE.TRACKING_PROJECT_STATE, scope.row.zt) }}
  57. </template>
  58. </el-table-column>
  59. <el-table-column prop="xzqmc" label="行政区" width="180" :show-overflow-tooltip="true" />
  60. <el-table-column
  61. :show-overflow-tooltip="true"
  62. prop="xmmc"
  63. label="项目名称"
  64. :min-width="320"
  65. />
  66. <el-table-column prop="gzry" label="跟踪人员" width="120" />
  67. <el-table-column prop="sfjc" label="是否进场" width="120">
  68. <template #default="scope">
  69. {{ scope.row.sfjc == '0' ? '是' : '否' }}
  70. </template>
  71. </el-table-column>
  72. <el-table-column
  73. prop="ygje"
  74. label="预估金额(元)"
  75. :show-overflow-tooltip="true"
  76. width="160"
  77. />
  78. <el-table-column
  79. prop="zbje"
  80. label="中标金额(元)"
  81. :show-overflow-tooltip="true"
  82. width="160"
  83. />
  84. <el-table-column prop="jf" label="甲方" width="220" :show-overflow-tooltip="true" />
  85. <el-table-column
  86. prop="jfdjr"
  87. label="甲方对接人"
  88. width="120"
  89. :show-overflow-tooltip="true"
  90. />
  91. <el-table-column
  92. prop="xmbm"
  93. label="项目归属部门"
  94. width="160"
  95. :show-overflow-tooltip="true"
  96. />
  97. <el-table-column prop="latestModifyTime" label="更新时间" width="180">
  98. <template #default="scope">
  99. {{ formatDate(scope.row.latestModifyTime) }}
  100. </template>
  101. </el-table-column>
  102. <el-table-column prop="xmjl" label="开关" width="100">
  103. <template #default="scope">
  104. <el-switch
  105. v-model="scope.row.status"
  106. :active-value="0"
  107. @change="switchChange(scope.row)"
  108. :inactive-value="1"
  109. />
  110. </template>
  111. </el-table-column>
  112. <el-table-column label="操作" width="80" fixed="right">
  113. <template #default="scope">
  114. <div class="operateBtn" @click="addOrEditHandle(scope.row)">
  115. <span>编辑</span>
  116. </div>
  117. </template>
  118. </el-table-column>
  119. </el-table>
  120. </div>
  121. <div class="pageBox">
  122. <el-pagination
  123. v-model:current-page="queryParams.pageNo"
  124. :page-size="queryParams.pageSize"
  125. background
  126. layout="total, prev, pager, next, jumper"
  127. :total="total"
  128. @current-change="handleCurrentChange"
  129. />
  130. </div>
  131. </div>
  132. <div class="editorConver" v-if="dialogVisible" :title="dialogTitle" width="660px" align-center>
  133. <el-form
  134. ref="ruleFormRef"
  135. style="width: 600px"
  136. label-width="auto"
  137. class="demo-ruleForm"
  138. status-icon
  139. >
  140. <el-form-item label="项目名称" prop="name">
  141. <el-input v-model="formData.xmmc" />
  142. </el-form-item>
  143. <el-row :gutter="20">
  144. <el-col :span="12">
  145. <el-form-item label="跟踪人员" prop="region">
  146. <UserOrgTree
  147. v-model="formData.gzryId"
  148. placeholder="请选择跟踪人员"
  149. @node-click="(item) => treeNodeClick(item, 'gzry')"
  150. />
  151. </el-form-item>
  152. </el-col>
  153. <el-col :span="12">
  154. <el-form-item label="甲方" prop="name">
  155. <el-input v-model="formData.jf" />
  156. </el-form-item>
  157. </el-col>
  158. </el-row>
  159. <el-row :gutter="20">
  160. <el-col :span="12">
  161. <el-form-item label="甲方对接人" prop="name">
  162. <el-input v-model="formData.jfdjr" />
  163. </el-form-item>
  164. </el-col>
  165. <el-col :span="12">
  166. <el-form-item label="是否进场" prop="region">
  167. <el-select v-model="formData.sfjc" style="width: 100%">
  168. <el-option label="是" :value="0" />
  169. <el-option label="否" :value="1" />
  170. </el-select>
  171. </el-form-item>
  172. </el-col>
  173. </el-row>
  174. <el-row :gutter="20">
  175. <el-col :span="12">
  176. <el-form-item label="预估金额(万元)" prop="name">
  177. <el-input v-model="formData.ygje" />
  178. </el-form-item>
  179. </el-col>
  180. <el-col :span="12">
  181. <el-form-item label="中标金额(万元)" prop="name">
  182. <el-input v-model="formData.zbje" />
  183. </el-form-item>
  184. </el-col>
  185. </el-row>
  186. <el-row :gutter="20">
  187. <el-col :span="12">
  188. <el-form-item label="项目归属部门" prop="region">
  189. <DeptTree
  190. v-model="formData.xmbmId"
  191. @node-click="(item) => treeNodeClick(item, 'xmbm')"
  192. placeholder="请选择部门"
  193. />
  194. </el-form-item>
  195. </el-col>
  196. <el-col :span="12">
  197. <el-form-item label="行政区" prop="region">
  198. <DistrictTree
  199. class="form-item-disable-style"
  200. placeholder="请选择行政区"
  201. v-model="formData.xzqdm"
  202. @node-click="(item, labels) => treeNodeClick(labels, 'xzqmc')"
  203. style="width: 100%"
  204. />
  205. </el-form-item>
  206. </el-col>
  207. </el-row>
  208. <el-row :gutter="20">
  209. <el-col :span="12">
  210. <el-form-item label="状态" prop="region">
  211. <el-select v-model="formData.zt" placeholder="请选择状态" style="width: 100%">
  212. <el-option
  213. v-for="(item, index) in getDictOptions(DICT_TYPE.TRACKING_PROJECT_STATE)"
  214. :key="index"
  215. :label="item.label"
  216. :value="item.value"
  217. />
  218. </el-select>
  219. </el-form-item>
  220. </el-col>
  221. <el-col :span="12">
  222. <el-form-item label="谁可见" prop="region">
  223. <UserOrgTree v-model="visibleUserIds" :multiple="true" placeholder="请选择跟谁可见" />
  224. </el-form-item>
  225. </el-col>
  226. </el-row>
  227. <el-form-item label="备注" prop="desc">
  228. <el-input v-model="formData.bz" type="textarea" />
  229. </el-form-item>
  230. </el-form>
  231. <div class="dialog-footer">
  232. <el-button @click="dialogVisible = false">关闭</el-button>
  233. <el-button type="primary" @click="saveProjectTracking"> 保存 </el-button>
  234. </div>
  235. </div>
  236. </div>
  237. </template>
  238. <script setup lang="ts">
  239. import { DICT_TYPE, getDictLabel, getDictOptions } from '@/utils/dict'
  240. import { IFormType, useMixins, infoList, user } from './common'
  241. import request from '@/config/axios'
  242. import { formatDate } from '@/utils/formatTime'
  243. import { getAssetURL } from '@/utils/auth'
  244. import UserOrgTree from '@/views/OaSystem/components/UserOrgTree/index.vue'
  245. import DeptTree from '@/views/OaSystem/components/DeptTree/index.vue'
  246. import DistrictTree from '@/views/OaSystem/components/DistrictTree/index.vue'
  247. defineOptions({ name: 'ProjectTrack' })
  248. const visibleUserIds = ref<string[]>([])
  249. const tableRef: any = ref(null)
  250. const tableHeight: any = ref(0)
  251. const { queryParams, formData, initFormData } = useMixins()
  252. const handleCurrentChange = (pageNo: number) => {
  253. queryParams.pageNo = pageNo
  254. queryProjectTrackByPage()
  255. }
  256. /**
  257. * 项目跟踪:新增、编辑
  258. */
  259. const dialogTitle = ref<string>('项目跟踪填报')
  260. const dialogVisible = ref<boolean>(false)
  261. const addOrEditHandle = (row?: IFormType) => {
  262. dialogVisible.value = true
  263. if (!row) {
  264. dialogTitle.value = '项目跟踪填报'
  265. initFormData()
  266. visibleUserIds.value = []
  267. } else {
  268. dialogTitle.value = '项目跟踪编辑'
  269. queryProjectTrackByDetail(row['id']).then((result) => {
  270. initFormData(result as any)
  271. visibleUserIds.value = result['visibleUserIds'].split(',')
  272. })
  273. }
  274. }
  275. const treeNodeClick = (item, type: string) => {
  276. if (!item) return
  277. if (type === 'xzqmc') {
  278. formData.value[type] = item.join('-')
  279. return
  280. }
  281. formData.value[type] = item['label'] || item['name']
  282. }
  283. const saveProjectTracking = async (): Promise<void> => {
  284. const urlApi = `/projectTracking/save`
  285. const sendData = {
  286. ...formData.value
  287. }
  288. sendData['visibleUserIds'] = visibleUserIds.value.join(',')
  289. const result = await request.post({ url: urlApi, data: sendData }, '/business')
  290. if (result) {
  291. searchHandle()
  292. dialogVisible.value = false
  293. }
  294. }
  295. const switchChange = (item) => {
  296. updateStatus({
  297. id: item['id'],
  298. status: item['status']
  299. })
  300. }
  301. const updateStatus = async (data: { id: string; status: string }): Promise<void> => {
  302. const urlApi = `/update-status`
  303. return await request.put({ url: urlApi, data: data }, '/business')
  304. }
  305. const tableData = ref<Array<any>>([])
  306. const total = ref<number>()
  307. const searchHandle: () => void = () => {
  308. queryParams.pageNo = 1
  309. queryProjectTrackingSummary()
  310. queryProjectTrackByPage()
  311. }
  312. const queryProjectTrackByPage = async (): Promise<void> => {
  313. const urlApi = `/projectTracking/page`
  314. const sendData = {
  315. ...queryParams
  316. }
  317. const result = await request.get({ url: urlApi, params: sendData }, '/business')
  318. tableData.value = result['list']
  319. total.value = result['total']
  320. }
  321. const queryProjectTrackByDetail = async (id: string): Promise<void> => {
  322. const urlApi = `/projectTracking/getById`
  323. const sendData = {
  324. id
  325. }
  326. return await request.get({ url: urlApi, params: sendData }, '/business')
  327. }
  328. queryProjectTrackByPage()
  329. /**
  330. * 项目金额、项目个数汇总
  331. */
  332. const queryProjectTrackingSummary = async (): Promise<void> => {
  333. const urlApi = `/projectTracking/summary`
  334. const sendData = {
  335. ...queryParams
  336. }
  337. const result = await request.get({ url: urlApi, params: sendData }, '/business')
  338. infoList[0]['num'] = result ? result.amount ?? 0 : 0
  339. infoList[1]['num'] = result ? result.nums ?? 0 : 0
  340. }
  341. queryProjectTrackingSummary()
  342. onMounted(() => {
  343. tableHeight.value = tableRef.value.clientHeight
  344. })
  345. </script>
  346. <style lang="scss" scoped>
  347. :deep(.el-radio) {
  348. margin-right: 10px;
  349. }
  350. </style>