FileManagementTab.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <template>
  2. <view>
  3. <!-- <view class="content-title" v-t="'PersonalManagement.Title.FileManagement'"></view>-->
  4. <view v-show="!loading" class="content-title">
  5. <view />
  6. <view v-if="isShowBtn" class="content-title-btns">
  7. <button hover-class="" v-if="!isShowBtn.isSHowIdentity" type="button"
  8. class="btn btn-danger btn-shadow waves-effect" @click="openAddFileDialog(1)">
  9. <view class="d-flex align-items-center">
  10. <cwg-icon name="crm-plus" :size="14" color="#fff" />
  11. <text v-t="'PersonalManagement.Title.ProofOfIdentity'" />
  12. </view>
  13. </button>
  14. <button hover-class="" v-if="!isShowBtn.isSHowAddress" type="button"
  15. class="btn btn-danger btn-shadow waves-effect" @click="openAddFileDialog(2)">
  16. <view class="d-flex align-items-center">
  17. <cwg-icon name="crm-plus" :size="14" color="#fff" />
  18. <text v-t="'PersonalManagement.Title.ProofOfAddress'" />
  19. </view>
  20. </button>
  21. <button hover-class="" type="button" class="btn btn-danger btn-shadow waves-effect"
  22. @click="openAddFileDialog(3)">
  23. <view class="d-flex align-items-center">
  24. <cwg-icon name="crm-plus" :size="14" color="#fff" />
  25. <text v-t="'PersonalManagement.Title.AttachedFile'" />
  26. </view>
  27. </button>
  28. </view>
  29. </view>
  30. <cwg-tabel ref="tableRef" :columns="columns" :api="customFileApi" :show-operation="false" :showPagination="false">
  31. <template #type="{ row }">
  32. <view :class="['status-badge', row.status]">{{ typeMap[row.type] }}</view>
  33. </template>
  34. <template #status="{ row }">
  35. <view class="table-cell-center">
  36. <view :class="['status-badge', row.status]">{{ stateMap[row.status] }}</view>
  37. </view>
  38. </template>
  39. <template #btn="{ row }">
  40. <view class="table-cell-center">
  41. <button hover-class="" class="btn-submit" :class="['operation-btn', row.status !== 4 ? 'disabled' : '']"
  42. :disabled="row.status !== 4" @click.stop="openAddFile(row)">
  43. <cwg-icon name="crm-image" :size="16" color="#1d293d" />
  44. <text v-t="'State.Again'" />
  45. </button>
  46. </view>
  47. </template>
  48. </cwg-tabel>
  49. <add-file-dialog ref="addFileDialog" @file-added="customFileList" @success="addSuccess" />
  50. </view>
  51. </template>
  52. <script setup lang="ts">
  53. import { computed, ref, onMounted, watch } from 'vue';
  54. import { useI18n } from 'vue-i18n';
  55. import AddFileDialog from './AddFileDialog.vue';
  56. const { t } = useI18n();
  57. import { personalApi } from '@/service/personal';
  58. const stateMap = computed(() => ({
  59. 1: t('State.ToBeProcessed'),
  60. 2: t('State.Completed'),
  61. 3: t('State.Refused'),
  62. 4: t('State.Again')
  63. }));
  64. const typeMap = computed(() => ({
  65. 1: t('PersonalManagement.Title.ProofOfIdentity'),
  66. 2: t('PersonalManagement.Title.ProofOfIdentity'),
  67. 3: t('PersonalManagement.Title.ProofOfAddress'),
  68. 4: t('PersonalManagement.Title.ProofOfAddress'),
  69. 10: t('PersonalManagement.Title.AttachedFile')
  70. }));
  71. const btnMap = computed(() => ({
  72. 1: t('PersonalManagement.Title.ProofOfIdentity'),
  73. 2: t('PersonalManagement.Title.ProofOfAddress'),
  74. 3: t('PersonalManagement.Title.AttachedFile')
  75. }));
  76. interface Props {
  77. icon: string;
  78. label: string;
  79. value: string;
  80. isLast?: boolean;
  81. }
  82. const tableRef = ref<any>(null);
  83. const tableData = computed(() => {
  84. return tableRef.value ? tableRef.value.tableData : [];
  85. });
  86. const loading = ref(false)
  87. const isShowBtn = ref()
  88. const setShowBtn = () => {
  89. const a = tableData.value
  90. let tableIdentity = [];
  91. const tableAddress = [];
  92. const tableAdditional = [];
  93. a.forEach((item) => {
  94. if (item.type == 1 || item.type == 2) {
  95. tableIdentity.push(item);
  96. } else if (item.type == 3) {
  97. tableAddress.push(item);
  98. } else {
  99. tableAdditional.push(item);
  100. }
  101. });
  102. const isSHowIdentity = tableIdentity.length > 1;
  103. const isSHowAddress = tableAddress.length > 0;
  104. isShowBtn.value = { isSHowIdentity, isSHowAddress };
  105. }
  106. // 表格列配置
  107. const columns = computed(() => [
  108. {
  109. prop: 'path',
  110. label: t('vu.item20'),
  111. type: 'file',
  112. align: 'center'
  113. },
  114. {
  115. prop: 'type',
  116. label: t('PersonalManagement.Label.FileName'),
  117. align: 'left',
  118. slot: 'type'
  119. },
  120. {
  121. prop: 'uploadTime',
  122. label: t('PersonalManagement.Label.UploadDate'),
  123. type: 'date',
  124. dateFormat: 'YYYY-MM-DD HH:mm',
  125. align: 'left'
  126. },
  127. {
  128. prop: 'status',
  129. label: t('PersonalManagement.Label.State'),
  130. type: 'tag',
  131. tagMap: { 1: '启用', 10: '禁用' },
  132. tagTypeMap: { 1: 'success', 0: 'danger' },
  133. slot: 'status',
  134. align: 'center'
  135. },
  136. {
  137. prop: 'btn',
  138. label: t('Label.Action'),
  139. slot: 'btn',
  140. align: 'center'
  141. }
  142. ])
  143. const addFileDialog = ref(null);
  144. const customFileApi = ref(null)
  145. customFileApi.value = personalApi.customFileList
  146. const openAddFileDialog = (type) => {
  147. addFileDialog.value.open({ type, title: btnMap.value[type], tableData: tableData.value });
  148. }
  149. const openAddFile = (row) => {
  150. if (row.status != 4) {
  151. return
  152. }
  153. let type
  154. switch (row.type) {
  155. case 1:
  156. type = 1
  157. break;
  158. case 2:
  159. type = 1
  160. break;
  161. case 3:
  162. type = 2
  163. break;
  164. case 10:
  165. type = 3
  166. break;
  167. }
  168. addFileDialog.value.open({ type, title: btnMap.value[type], tableData: tableData.value, currentFile: row });
  169. }
  170. const addSuccess = () => {
  171. tableRef.value.refreshTable()
  172. }
  173. watch(tableData, (newVal) => {
  174. if (newVal && newVal.length > 0) {
  175. loading.value = true
  176. setShowBtn()
  177. setTimeout(() => {
  178. loading.value = false
  179. }, 300)
  180. }
  181. }, { immediate: true })
  182. defineProps<Props>();
  183. </script>
  184. <style scoped lang="scss">
  185. @import "@/uni.scss";
  186. .btn {
  187. margin: 0;
  188. }
  189. .avatar {
  190. width: px2rpx(60);
  191. height: px2rpx(60);
  192. border-radius: 4px;
  193. }
  194. .content-title {
  195. display: flex;
  196. justify-content: space-between;
  197. align-items: center;
  198. font-size: px2rpx(20);
  199. font-weight: 500;
  200. .content-title-btns {
  201. margin: px2rpx(8) 0;
  202. display: flex;
  203. align-items: center;
  204. justify-content: flex-end;
  205. //flex-wrap: wrap;
  206. gap: px2rpx(5);
  207. .btn-primary {
  208. min-width: px2rpx(80);
  209. background-color: var(--color-error);
  210. color: white;
  211. padding: 0 px2rpx(10);
  212. border: none;
  213. border-radius: px2rpx(8);
  214. font-size: px2rpx(16);
  215. text-align: center;
  216. cursor: pointer;
  217. display: flex;
  218. align-items: center;
  219. justify-content: center;
  220. box-sizing: border-box;
  221. //gap: px2rpx(5);
  222. }
  223. .btn-primary:active {
  224. background-color: #cf1322;
  225. ;
  226. }
  227. }
  228. }
  229. .operation-btn {
  230. display: flex;
  231. width: auto;
  232. align-items: center;
  233. justify-content: center;
  234. padding: 0 px2rpx(10);
  235. box-sizing: border-box;
  236. height: px2rpx(36);
  237. line-height: px2rpx(36);
  238. :deep(span) {
  239. font-size: px2rpx(14);
  240. }
  241. }
  242. .table-cell-center {
  243. display: flex;
  244. justify-content: center;
  245. align-items: center;
  246. width: 100%;
  247. }
  248. .operation-btn.disabled {
  249. cursor: not-allowed;
  250. opacity: 0.5;
  251. :deep(span) {
  252. cursor: not-allowed;
  253. }
  254. }
  255. </style>