index.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. <template>
  2. <div class="hc-layout-box">
  3. <div class="hc-layout-left-box">
  4. <div class="user-avatar-box">
  5. <div class="user-avatar" v-loading="avatarLoading">
  6. <img :src="userInfo['avatar'] || avatarPng" alt="" crossOrigin="anonymous"/>
  7. <div class="user-avatar-upload">
  8. <el-upload class="upload-dom" :action="action" :accept="accept" :headers="getTokenHeader()" :data="upData" :show-file-list="false" :on-success="uploadFinish" :on-error="uploadError" :before-upload="beforeUpload">
  9. <HcIcon name="camera" fill/>
  10. </el-upload>
  11. </div>
  12. </div>
  13. <div class="user-name truncate">{{ userInfo['real_name'] || '游客' }}</div>
  14. </div>
  15. <div class="user-menu-box">
  16. <el-scrollbar>
  17. <HcMenuSimple :datas="menuOptions" :keys="menuKey" @change="handleMenuValue"/>
  18. </el-scrollbar>
  19. </div>
  20. </div>
  21. <div class="hc-layout-content-box">
  22. <HcCard scrollbar :title="menuItem.label" :ui="basicHight?'basic-hight':''" v-if="menuKey !== 'log' && menuKey !== 'recycle'">
  23. <template #extra>
  24. <span class="text-link" v-if="menuKey === 'basic' && !basicFormEdit" @click="basicFormEditClick">编辑</span>
  25. <span class="text-link" v-if="menuKey === 'project'" @click="setDefaultProjectClick">设置默认项目</span>
  26. </template>
  27. <template v-if="menuKey === 'basic'">
  28. <el-form ref="formUserRef" :model="formUserModel" :rules="formUserRules" size="large" label-position="top">
  29. <el-row :gutter="20">
  30. <el-col :span="12">
  31. <el-form-item label="用户名称">
  32. <el-input v-model="formUserModel.real_name" disabled/>
  33. </el-form-item>
  34. </el-col>
  35. <el-col :span="12">
  36. <el-form-item label="登录账号">
  37. <el-input v-model="formUserModel.account" placeholder="" disabled/>
  38. </el-form-item>
  39. </el-col>
  40. <el-col :span="12">
  41. <el-form-item label="身份证号">
  42. <el-input v-model="formUserModel.idNumber" placeholder="" disabled/>
  43. </el-form-item>
  44. </el-col>
  45. <el-col :span="12">
  46. <el-form-item label="绑定手机" :prop="basicFormEdit?'phone':''">
  47. <el-input v-model="formUserModel.phone" placeholder="请输入绑定手机" :disabled="!basicHight"/>
  48. </el-form-item>
  49. </el-col>
  50. <el-col :span="12">
  51. <el-form-item label="所属角色">
  52. <el-input v-model="formUserModel.roleName" placeholder="" disabled/>
  53. </el-form-item>
  54. </el-col>
  55. <el-col :span="12">
  56. <el-form-item label="所属部门">
  57. <el-input v-model="formUserModel.deptId" placeholder="" disabled/>
  58. </el-form-item>
  59. </el-col>
  60. <el-col :span="12">
  61. <el-form-item label="CA签字体">
  62. <el-image style="height: 60px" :src="formUserModel?.signatureUrl" :preview-src-list="[formUserModel?.signatureUrl]" :initial-index="0" fit="cover" v-if="formUserModel?.signatureUrl"/>
  63. <span class="text-zinc-400" v-else>无CA签字体</span>
  64. </el-form-item>
  65. </el-col>
  66. </el-row>
  67. </el-form>
  68. </template>
  69. <template v-if="menuKey === 'password'">
  70. <el-form ref="formUserPassRef" :model="formUserPassModel" :rules="formUserPassRules" size="large" label-position="top" style="max-width: 400px; margin: auto;">
  71. <el-form-item label="原始密码" prop="oldPassword">
  72. <el-input type="password" v-model="formUserPassModel.oldPassword" placeholder="请输入原始密码" show-password/>
  73. </el-form-item>
  74. <el-form-item label="新的密码" prop="newPassword">
  75. <el-input type="password" v-model="formUserPassModel.newPassword" placeholder="请输入新的密码" show-password/>
  76. </el-form-item>
  77. <el-form-item label="确认新密码" prop="newPassword1">
  78. <el-input type="password" v-model="formUserPassModel.newPassword1" placeholder="请输入确认新密码" show-password/>
  79. </el-form-item>
  80. </el-form>
  81. </template>
  82. <template v-if="menuKey === 'project'">
  83. <el-menu :default-active="projectKey" class="hc-project-menu" unique-opened>
  84. <el-sub-menu v-for="item in projectContractArr" :index="item.id">
  85. <template #title>
  86. <HcIcon name="folder-2" class="hc-menu-icon"/>
  87. <span>{{ item?.name }}</span>
  88. </template>
  89. <el-menu-item v-for="items in item?.contractInfoList ?? []" :index="items?.id" @click="projectMenuValue(item,items)">
  90. <HcIcon name="star" class="hc-menu-icon" fill v-if="projectKey === items?.id"/>
  91. <span>{{ items?.name }}</span>
  92. </el-menu-item>
  93. </el-sub-menu>
  94. </el-menu>
  95. </template>
  96. </HcCard>
  97. <div class="hc-card-foot-box" v-if="basicFormEdit">
  98. <el-button type="primary" hc-btn :loading="saveUserLoading" @click="saveUserInfoClick">
  99. <HcIcon name="save"/>
  100. <span>保存</span>
  101. </el-button>
  102. <el-button hc-btn @click="cancelUserClick">
  103. <HcIcon name="close"/>
  104. <span>取消</span>
  105. </el-button>
  106. </div>
  107. <HcCard :title="menuItem.label" v-if="menuKey === 'log'">
  108. <template #search>
  109. <div class="flex items-center">
  110. <div class="w-32">
  111. <el-select v-model="searchLogForm.operationModule" placeholder="业务模块" clearable @change="BusinessModuleValue">
  112. <el-option v-for="item in operationModuleData" :key="item.value" :label="item?.dictValue" :value="item?.dictKey"/>
  113. </el-select>
  114. </div>
  115. <div class="w-32 ml-2">
  116. <el-select v-model="searchLogForm.operationView" placeholder="页面" clearable @change="OperationViewValue">
  117. <el-option v-for="item in operationViewData" :key="item.value" :label="item?.dictValue" :value="item?.dictKey"/>
  118. </el-select>
  119. </div>
  120. <div class="w-40 ml-2">
  121. <el-select v-model="searchLogForm.operationType" placeholder="操作类型" clearable>
  122. <el-option v-for="item in operationTypeData" :key="item.value" :label="item?.dictValue" :value="item?.dictKey"/>
  123. </el-select>
  124. </div>
  125. <div class="w-20 ml-2">
  126. <el-select v-model="searchLogForm.operationMedium" placeholder="设备" clearable>
  127. <el-option v-for="item in deviceData" :key="item.value" :label="item?.label" :value="item?.value"/>
  128. </el-select>
  129. </div>
  130. <div class="w-64 ml-2">
  131. <HcDatePicker :dates="betweenTime" clearable @change="betweenDateUpdate"/>
  132. </div>
  133. <div class="w-60 ml-2">
  134. <el-input v-model="searchLogForm.queryValue" placeholder="请输入名称关键词检索" clearable @keyup="keyUpEvent"/>
  135. </div>
  136. <div class="ml-2">
  137. <el-button type="primary" @click="searchClick">
  138. <HcIcon name="search-2"/>
  139. <span>搜索</span>
  140. </el-button>
  141. </div>
  142. </div>
  143. </template>
  144. <HcTable :column="logTableColumn" :datas="logTableData" :loading="logTableLoading">
  145. <template #operationContent="{row}">
  146. <div class="text-link text-cut" @click="tableOperationContent(row)">{{row?.operationContent}}</div>
  147. </template>
  148. </HcTable>
  149. <template #action>
  150. <HcPages :pages="searchLogForm" @change="pageLogChange"/>
  151. </template>
  152. </HcCard>
  153. <HcCard v-if="menuKey === 'recycle'" actionSize="lg">
  154. <template #header>
  155. <div class="mr-5">{{menuItem.label}}</div>
  156. <HcNewSwitch :datas="userTypeTab" :keys="userTypeKey" @change="userTypeChange"/>
  157. </template>
  158. <template #extra>
  159. <HcNewSwitch :datas="tabTypeTab" :keys="tabTypeKey" @change="tabTypeChange"/>
  160. </template>
  161. <HcTable ref="recycleTableRef" :column="recycleTableColumn" :datas="recycleTableData" :loading="recycleTableLoading" isCheck @selection-change="recycleTableSelectionChange"/>
  162. <template #action>
  163. <div class="foot-recycle">
  164. <el-button type="primary" hc-btn :disabled="userTypeKey === '2'" :loading="recycleBtnLoading" @click="recycleBtnClick">
  165. <HcIcon name="reply" fill/>
  166. <span>恢复</span>
  167. </el-button>
  168. <HcPages :pages="searchRecycleForm" @change="pageRecycleChange"/>
  169. </div>
  170. </template>
  171. </HcCard>
  172. </div>
  173. <!--日志内容-->
  174. <el-dialog v-model="operationContentModal" title="日志内容" width="38rem" class="hc-modal-border">
  175. {{operationContent}}
  176. </el-dialog>
  177. </div>
  178. </template>
  179. <script setup>
  180. import {ref, onMounted} from "vue";
  181. import {useAppStore} from "~src/store";
  182. import userApi from "~api/userInfo/index"
  183. import {useRouter, useRoute} from 'vue-router'
  184. import avatarPng from '~src/assets/images/avatar.png';
  185. import {getTokenHeader} from '~src/api/request/header';
  186. import {getIndex,formValidate,getArrValue,isMobile} from "vue-utils-plus"
  187. import md5 from 'js-md5';
  188. //初始变量
  189. const router = useRouter()
  190. const useRoutes = useRoute()
  191. const useAppState = useAppStore()
  192. //全局变量信息
  193. const userInfo = ref(useAppState.getUserInfo);
  194. const projectId = ref(useAppState.getProjectId);
  195. const contractId = ref(useAppState.getContractId);
  196. const projectContractArr = ref(useAppState.getProjectContract);
  197. //路由参数数据
  198. const routerQuery = useRoutes?.query;
  199. let MenuType = routerQuery?.MenuType || 'basic'
  200. //上传组件参数
  201. const action = '/api/blade-resource/oss/endpoint/put-file';
  202. const accept = 'image/png,image/jpg,image/jpeg';
  203. const upData = ref({})
  204. //上传前
  205. const avatarLoading = ref(false)
  206. const beforeUpload = () => {
  207. avatarLoading.value = true
  208. return true
  209. }
  210. //上传完成
  211. const uploadFinish = async (res) => {
  212. const link = res?.data?.link ?? '';
  213. const user_id = userInfo.value?.user_id ?? '';
  214. if (link) {
  215. const { error, code } = await userApi.updateUserInfo({avatar: link, id: user_id})
  216. if (!error && code === 200) {
  217. avatarLoading.value = false
  218. userInfo.value.avatar = link
  219. window?.$message?.success('更换头像成功')
  220. useAppState.setUserInfo(userInfo.value)
  221. } else {
  222. avatarLoading.value = false
  223. }
  224. } else {
  225. window?.$message?.warning('上传头像异常,请稍后再试')
  226. avatarLoading.value = false
  227. }
  228. }
  229. //上传失败
  230. const uploadError = () => {
  231. avatarLoading.value = false
  232. window?.$message?.warning('上传头像失败')
  233. }
  234. //左侧菜单
  235. const menuKey = ref(MenuType)
  236. const menuItem = ref({})
  237. const menuOptions = ref([
  238. {key: 'basic', label: '基础信息', icon: 'user-3'},
  239. {key: 'password', label: '密码设置', icon: 'lock-unlock'},
  240. {key: 'project', label: '参建项目', icon: 'folder-2'},
  241. {key: 'log', label: '操作日志', icon: 'file-mark'},
  242. {key: 'recycle', label: '回收站', icon: 'delete-bin-5'},
  243. ]);
  244. //获取菜单对象数据
  245. const menuObjItem = () => {
  246. const index = getIndex(menuOptions.value, 'key', menuKey.value)
  247. menuItem.value = menuOptions.value[index]
  248. }
  249. //菜单被点击
  250. const handleMenuValue = (item) => {
  251. menuItem.value = item
  252. menuKey.value = item?.key
  253. router.push({
  254. path: useRoutes.path,
  255. query: {
  256. MenuType: item?.key
  257. }
  258. })
  259. getPageTypeData(item?.key)
  260. }
  261. //渲染完成
  262. onMounted(() => {
  263. menuObjItem()
  264. getPageTypeData(menuKey.value)
  265. })
  266. //根据类型,获取相关数据
  267. const getPageTypeData = (key) => {
  268. //编辑状态
  269. if (key === 'password') {
  270. basicFormEdit.value = true
  271. basicHight.value = true
  272. } else {
  273. basicFormEdit.value = false
  274. basicHight.value = false
  275. }
  276. //请求数据
  277. if (key === 'basic') {
  278. queryCurrentUserData()
  279. } else if (key === 'project') {
  280. getDefaultProject()
  281. } else if (key === 'log') {
  282. queryBusinessModule()
  283. queryOperationView()
  284. operationTypeStatus()
  285. getLogTableData()
  286. } else if (key === 'recycle') {
  287. getRecycleTableData()
  288. }
  289. }
  290. //是否编辑
  291. const basicFormEdit = ref(false)
  292. const basicHight = ref(false)
  293. //基础信息表单
  294. const formUserRef = ref(null)
  295. const formUserModel = ref(userInfo.value)
  296. const formUserRules = {
  297. phone: {
  298. required: true,
  299. validator: (rule, value, callback) => {
  300. if (!value) {
  301. callback(new Error('请输入手机号'))
  302. } else if (!isMobile(value)) {
  303. callback(new Error('手机号码格式错误'))
  304. } else {
  305. callback()
  306. }
  307. },
  308. trigger: "blur"
  309. },
  310. }
  311. //获取用户信息
  312. const queryCurrentUserData = async () => {
  313. const { error, code, data } = await userApi.queryCurrentUserData()
  314. if (!error && code === 200) {
  315. formUserModel.value.deptId = data?.deptId || ''
  316. formUserModel.value.idNumber = data?.idNumber || ''
  317. formUserModel.value.roleName = data?.roleName || ''
  318. formUserModel.value.signatureUrl = data?.signatureUrl || ''
  319. }
  320. }
  321. //切换编辑模式
  322. const basicFormEditClick = () => {
  323. basicFormEdit.value = true
  324. basicHight.value = true
  325. }
  326. //保存数据
  327. const saveUserLoading = ref(false)
  328. const saveUserInfoClick = () => {
  329. const key = menuKey.value
  330. if (key === 'basic') {
  331. saveUserInfoData()
  332. } else if (key === 'password') {
  333. saveUpdatePassword()
  334. }
  335. }
  336. //取消修改
  337. const cancelUserClick = () => {
  338. const key = menuKey.value
  339. if (key === 'basic') {
  340. basicFormEdit.value = false
  341. basicHight.value = false
  342. } else {
  343. console.log('我也不知道这个点了干什么,反正UI图上有,至于有什么作用,不知道。。')
  344. }
  345. }
  346. //保存用户信息
  347. const saveUserInfoData = async () => {
  348. const { phone, user_id } = formUserModel.value
  349. if (phone && isMobile(phone)) {
  350. saveUserLoading.value = true
  351. const { error, code } = await userApi.updateUserInfo({
  352. phone: phone,
  353. id: user_id
  354. })
  355. if (!error && code === 200) {
  356. saveUserLoading.value = false
  357. window?.$message?.success('保存成功')
  358. userInfo.value.phone = phone
  359. useAppState.setUserInfo(userInfo.value)
  360. } else {
  361. saveUserLoading.value = false
  362. }
  363. }
  364. }
  365. //密码设置表单
  366. const formUserPassRef = ref(null)
  367. const formUserPassModel = ref({oldPassword: '', newPassword: '', newPassword1: ''})
  368. const formUserPassRules = {
  369. oldPassword: {
  370. required: true,
  371. trigger: "blur",
  372. message: "请输入原始密码"
  373. },
  374. newPassword: {
  375. required: true,
  376. validator(rule, value, callback) {
  377. const pass = formUserPassModel.value.newPassword1;
  378. if (!value) {
  379. callback(new Error("请输入新的密码"))
  380. } else if (pass && value !== pass) {
  381. callback(new Error("新的密码和确认新密码不一致"))
  382. }
  383. callback()
  384. },
  385. trigger: "blur"
  386. },
  387. newPassword1: {
  388. required: true,
  389. validator(rule, value, callback) {
  390. const pass = formUserPassModel.value.newPassword;
  391. if (!value) {
  392. callback(new Error("请输入确认新密码"))
  393. } else if (pass && value !== pass) {
  394. callback(new Error("新的密码和确认新密码不一致"))
  395. }
  396. callback()
  397. },
  398. trigger: "blur"
  399. }
  400. }
  401. //更新密码
  402. const saveUpdatePassword = async () => {
  403. const res = await formValidate(formUserPassRef.value)
  404. if (res) {
  405. const form = formUserPassModel.value;
  406. saveUserLoading.value = true
  407. const { error, code } = await userApi.updatePassword({
  408. oldPassword: md5(form?.oldPassword),
  409. newPassword: md5(form?.newPassword),
  410. newPassword1: md5(form?.newPassword1),
  411. plaintextPassword: form?.newPassword
  412. })
  413. if (!error && code === 200) {
  414. saveUserLoading.value = false
  415. window?.$message?.success('密码修改成功')
  416. formUserPassModel.value = {
  417. oldPassword: '',
  418. newPassword: '',
  419. newPassword1: ''
  420. }
  421. } else {
  422. saveUserLoading.value = false
  423. }
  424. }
  425. }
  426. //获取默认项目
  427. const projectKey = ref(null)
  428. const getDefaultProject = async () => {
  429. const { error, code, data } = await userApi.getDefaultProject()
  430. if (!error && code === 200) {
  431. projectKey.value = data['contractId']
  432. }
  433. }
  434. //项目被选择
  435. const menuProjectId = ref('')
  436. const menuContractId = ref('')
  437. const projectMenuValue = (item,items) => {
  438. menuProjectId.value = item?.id
  439. menuContractId.value = items?.id
  440. projectKey.value = items?.id
  441. }
  442. //设置为默认项目
  443. const setDefaultProjectClick = async () => {
  444. const pid = menuProjectId.value, cid = menuContractId.value
  445. if (pid && cid) {
  446. const { error, code } = await userApi.setDefaultProject({
  447. projectId: pid,
  448. contractId: cid
  449. })
  450. if (!error && code === 200) {
  451. window?.$message?.success('设置成功')
  452. }
  453. } else {
  454. window?.$message?.warning('请先在下方选择一个项目合同段')
  455. }
  456. }
  457. //搜索和分页数据
  458. const searchLogForm = ref({
  459. operationModule: null, operationView: null, operationType: null, operationMedium: null,
  460. queryValue: null, startTime: null, endTime: null,
  461. current: 1, size: 10, total: 0
  462. })
  463. //业务模块
  464. const operationModuleData = ref([])
  465. const queryBusinessModule = async () => {
  466. const { error, code, data } = await userApi.queryBusinessModule()
  467. if (!error && code === 200) {
  468. operationModuleData.value = data
  469. } else {
  470. operationModuleData.value = []
  471. }
  472. }
  473. const BusinessModuleValue = () => {
  474. searchLogForm.value.operationView = null
  475. searchLogForm.value.operationType = null
  476. queryOperationView()
  477. operationTypeStatus()
  478. }
  479. //页面
  480. const operationViewData = ref([])
  481. const queryOperationView = async () => {
  482. const { error, code, data } = await userApi.queryOperationView({
  483. businessModule: searchLogForm.value?.operationModule || ''
  484. })
  485. if (!error && code === 200) {
  486. operationViewData.value = data
  487. } else {
  488. operationViewData.value = []
  489. }
  490. }
  491. const OperationViewValue = () => {
  492. searchLogForm.value.operationType = null
  493. operationTypeStatus()
  494. }
  495. //操作类型
  496. const operationTypeData = ref([])
  497. const operationTypeStatus = async () => {
  498. const { error, code, data } = await userApi.queryOperationTypeList({
  499. businessModule: searchLogForm.value?.operationModule || '',
  500. operationView: searchLogForm.value?.operationView || ''
  501. })
  502. if (!error && code === 200) {
  503. operationTypeData.value = data
  504. } else {
  505. operationTypeData.value = []
  506. }
  507. }
  508. //设备
  509. const deviceData = ref([{label: "APP", value: "APP"}, {label: "PC", value: "PC"}])
  510. //表格数据
  511. const logTableColumn = ref([
  512. {key:'operationModule', name: '业务模块', width: '180'},
  513. {key:'operationTypeValue', name: '操作类型', width: '220'},
  514. {key:'operationMedium', name: '设备', align: 'center', width: '80'},
  515. {key:'operationContent', name: '操作内容'},
  516. {key:'createTime', name: '操作时间', align: 'center', width: '180'},
  517. ])
  518. const logTableData = ref([]);
  519. //日期时间被选择
  520. const betweenTime = ref(null)
  521. const betweenDateUpdate = ({val,arr}) => {
  522. betweenTime.value = arr
  523. searchLogForm.value.startTime = val?.start
  524. searchLogForm.value.endTime = val?.end
  525. }
  526. //回车搜索
  527. const keyUpEvent = (e) => {
  528. if (e.key === "Enter") {
  529. searchLogForm.value.current = 1;
  530. getLogTableData()
  531. }
  532. }
  533. //搜索
  534. const searchClick = () => {
  535. searchLogForm.value.current = 1;
  536. getLogTableData()
  537. }
  538. //分页被点击
  539. const pageLogChange = ({current, size}) => {
  540. searchLogForm.value.current = current
  541. searchLogForm.value.size = size
  542. getLogTableData()
  543. }
  544. //获取数据
  545. const logTableLoading = ref(false)
  546. const getLogTableData = async () => {
  547. logTableLoading.value = true
  548. const { error, code, data } = await userApi.getOperationLog({
  549. projectId: projectId.value,
  550. contractId: contractId.value,
  551. ...searchLogForm.value
  552. })
  553. logTableLoading.value = false
  554. if (!error && code === 200) {
  555. logTableData.value = getArrValue(data['records'])
  556. searchLogForm.value.total = data.total || 0
  557. } else {
  558. logTableData.value = []
  559. searchLogForm.value.total = 0
  560. }
  561. }
  562. //查看日志内容
  563. const operationContentModal = ref(false)
  564. const operationContent = ref('')
  565. const tableOperationContent = (row) => {
  566. operationContent.value = row['operationContent'] ?? ''
  567. operationContentModal.value = true
  568. }
  569. //个人和全部切换
  570. const userTypeKey = ref('1')
  571. const userTypeTab = ref([{key:'1', name: '个人'}, {key:'2', name: '全部'}]);
  572. const userTypeChange = (item) => {
  573. userTypeKey.value = item?.key;
  574. if (item?.key === '1') {
  575. searchRecycleForm.value.createUserName = ''
  576. } else {
  577. searchRecycleForm.value.createUserName = 'ALL'
  578. }
  579. getRecycleTableData()
  580. }
  581. //结构类型tab数据和相关处理
  582. const tabTypeKey = ref('1')
  583. const tabTypeTab = ref([
  584. {key: '1', name: '文件资料'},
  585. {key: '2', name: '工程划分'}
  586. ]);
  587. const tabTypeChange = (item) => {
  588. tabTypeKey.value = item?.key;
  589. tabTypeKey.value = item?.key;
  590. searchRecycleForm.value.current = 1
  591. searchRecycleForm.value.delType = item?.key
  592. getRecycleTableData()
  593. }
  594. //搜索和分页数据
  595. const searchRecycleForm = ref({
  596. projectId: projectId.value, contractId: contractId.value, createUserName: '',
  597. delType: tabTypeKey.value, current: 1, size: 20, total: 0
  598. })
  599. //表格数据
  600. const recycleTableRef = ref(null)
  601. const recycleTableColumn = ref([
  602. {key:'fileName', name: '删除内容'},
  603. {key:'position', name: '父节点名称'},
  604. {key:'createUserName', name: '操作人'},
  605. {key:'operationTime', name: '删除时间', align: 'center', width: '180'},
  606. ])
  607. const recycleTableLoading = ref(false)
  608. const recycleTableData = ref(null);
  609. //分页被点击
  610. const pageRecycleChange = ({current, size}) => {
  611. searchRecycleForm.value.current = current
  612. searchRecycleForm.value.size = size
  613. getRecycleTableData()
  614. }
  615. //获取数据
  616. const getRecycleTableData = async () => {
  617. const { error, code, data } = await userApi.queryRecycleBinList({
  618. projectId: projectId.value,
  619. contractId: contractId.value,
  620. delType: tabTypeKey.value,
  621. ...searchRecycleForm.value
  622. })
  623. if (!error && code === 200) {
  624. recycleTableData.value = getArrValue(data['records'])
  625. searchRecycleForm.value.total = data.total || 0
  626. } else {
  627. recycleTableData.value = []
  628. searchRecycleForm.value.total = 0
  629. }
  630. }
  631. //多选
  632. const RecycleCheckedKeys = ref([]);
  633. const recycleTableSelectionChange = (val) => {
  634. RecycleCheckedKeys.value = val
  635. }
  636. //恢复
  637. const recycleBtnLoading = ref(false)
  638. const recycleBtnClick = async () => {
  639. const rows = RecycleCheckedKeys.value
  640. if (rows.length > 0) {
  641. //请求数据
  642. recycleBtnLoading.value = true
  643. const { error, code } = await userApi.recycleBinRegain({
  644. projectId: projectId.value,
  645. contractId: contractId.value,
  646. delType: tabTypeKey.value,
  647. regainIds: rows
  648. })
  649. recycleBtnLoading.value = false
  650. if (!error && code === 200) {
  651. window?.$message?.success('操作成功')
  652. searchRecycleForm.value.current = 1
  653. getRecycleTableData()
  654. }
  655. } else {
  656. window.$message?.warning('请先勾选要恢复的数据')
  657. }
  658. }
  659. </script>
  660. <style lang="scss" scoped>
  661. @import "../../styles/user/index.scss";
  662. </style>
  663. <style lang="scss">
  664. .user-avatar-upload .upload-dom, .upload-dom .el-upload {
  665. height: 100%;
  666. width: 100%;
  667. }
  668. </style>