index.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <template>
  2. <div class="page page-full border bg padding">
  3. <el-form inline ref="queryRef" @keyup.enter="getList(1)">
  4. <el-form-item :label="$t('message.property.dossier.form.keyword') + ':'" prop="keyWord">
  5. <el-input v-model="params.keyWord" :placeholder="$t('message.property.dossier.form.keywordPlaceholder')" clearable style="width: 240px" />
  6. </el-form-item>
  7. <el-form-item>
  8. <el-button type="primary" class="ml10" @click="getList(1)">
  9. <el-icon>
  10. <ele-Search />
  11. </el-icon>
  12. {{ $t('message.tableI18nAction.query') }}
  13. </el-button>
  14. </el-form-item>
  15. <el-form-item>
  16. <el-button type="info" @click="batchdel()" v-auth="'batchdel'">
  17. <el-icon>
  18. <ele-FolderAdd />
  19. </el-icon>
  20. {{ $t('message.tableI18nAction.delete') }}
  21. </el-button>
  22. </el-form-item>
  23. </el-form>
  24. <div class="page page-full-part flex-row gap-4">
  25. <el-card style="width: 250px;" shadow="never">
  26. <el-tree :data="mergedData" :props="defaultProps" accordion default-expand-all @node-click="handleNodeClick" :node-key="'id'" highlight-current>
  27. <template #default="{ node, data }">
  28. <div class="custom-tree-node">
  29. <span class="tree-label">
  30. <el-icon v-if="data.is_type != '2'">
  31. <Folder />
  32. </el-icon>
  33. <SvgIcon name="iconfont icon-siweidaotu" v-else></SvgIcon>
  34. {{ node.label }}
  35. </span>
  36. </div>
  37. </template>
  38. </el-tree>
  39. </el-card>
  40. <el-card class="flex1" shadow="never">
  41. <div class="page page-full">
  42. <el-table :data="tableData" style="width: 100%" @selection-change="handleSelectionChange" row-key="id" v-loading="loading">
  43. <el-table-column type="selection" width="55" align="center" />
  44. <el-table-column prop="deviceName" v-col="'deviceName'" :label="$t('message.property.dossier.columns.deviceName')" min-width="100" show-overflow-tooltip />
  45. <el-table-column prop="deviceKey" v-col="'deviceKey'" :label="$t('message.property.dossier.columns.deviceKey')" show-overflow-tooltip />
  46. <el-table-column prop="deviceNumber" v-col="'deviceNumber'" :label="$t('message.property.dossier.columns.deviceNumber')" show-overflow-tooltip />
  47. <el-table-column prop="deviceCategory" v-col="'deviceCategory'" :label="$t('message.property.dossier.columns.deviceCategory')" show-overflow-tooltip />
  48. <el-table-column prop="installTime" v-col="'installTime'" :label="$t('message.property.dossier.columns.installTime')" width="160" align="center" />
  49. <el-table-column :label="$t('message.tableI18nColumn.operation')" width="160" align="center">
  50. <template #default="scope">
  51. <el-button size="small" text type="warning" v-auth="'edit'" @click="addOrEdit(scope.row)">{{ $t('message.tableI18nAction.edit') }}</el-button>
  52. <el-button size="small" text type="info" v-auth="'del'" @click="del(scope.row)">{{ $t('message.tableI18nAction.delete') }}</el-button>
  53. </template>
  54. </el-table-column>
  55. </el-table>
  56. <pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize" @pagination="getList()" />
  57. </div>
  58. </el-card>
  59. </div>
  60. <EditForm ref="editFormRef" @getList="getList(1)"></EditForm>
  61. </div>
  62. </template>
  63. <script lang="ts" setup>
  64. import device from '/@/api/device'
  65. import { useSearch } from '/@/hooks/useCommon'
  66. import { Folder } from '@element-plus/icons-vue'
  67. import { ElMessageBox, ElMessage } from 'element-plus'
  68. import EditForm from './edit.vue'
  69. import { useI18n } from 'vue-i18n'
  70. interface Tree {
  71. label: string
  72. children?: Tree[]
  73. }
  74. import { ref, onMounted } from 'vue'
  75. const defaultProps = {
  76. children: 'children',
  77. label: 'label',
  78. }
  79. const queryRef = ref()
  80. const { t } = useI18n()
  81. const productData = ref([])
  82. const mergedData = ref()
  83. const cateData = ref()
  84. const editFormRef = ref()
  85. const productIno = ref()
  86. const deviceKeys = ref<number[]>([])
  87. const { params, tableData, getList, loading } = useSearch<any[]>(device.dev_asset.getList, 'Data', { keyWord: '' })
  88. getList()
  89. const handleSelectionChange = (selection: any[]) => {
  90. deviceKeys.value = selection.map((item) => item.deviceKey);
  91. };
  92. onMounted(() => {
  93. getCateList()
  94. })
  95. const addOrEdit = async (row?: any) => {
  96. if (row) {
  97. editFormRef.value.open(row, productIno.value)
  98. return
  99. } else {
  100. editFormRef.value.open({}, productIno.value)
  101. }
  102. }
  103. const getCateList = () => {
  104. device.category.getList({}).then((res: any) => {
  105. cateData.value = res.category
  106. device.product.getLists({}).then((res: any) => {
  107. productData.value = res.product
  108. mergedData.value = matchProductsToCategories(productData.value, cateData.value)
  109. })
  110. })
  111. }
  112. const handleNodeClick = (data: any) => {
  113. if (data.is_type === '2') {
  114. productIno.value = data
  115. params.productKey = data.key
  116. getList()
  117. } else {
  118. productIno.value = ''
  119. }
  120. }
  121. const matchProductsToCategories = (productData: any, cateData: any) => {
  122. const treeData = []
  123. for (let category of cateData) {
  124. const treeNode = buildTree(category, productData)
  125. treeData.push(treeNode)
  126. }
  127. return treeData
  128. }
  129. const buildTree = (category: any, productData: any) => {
  130. const treeNode = {
  131. id: category.id,
  132. label: category.name,
  133. key: category.key,
  134. is_type: '1', // 1是分类
  135. children: [] as any[],
  136. }
  137. if (category.children && category.children.length > 0) {
  138. const products = productData.filter((product: any) => product.categoryId === category.id)
  139. for (let product of products) {
  140. const productNode = {
  141. id: product.id,
  142. label: product.name,
  143. key: product.key,
  144. is_type: '2', // 2是产品
  145. }
  146. treeNode.children.push(productNode)
  147. }
  148. for (let child of category.children) {
  149. const childNode = buildTree(child, productData)
  150. treeNode.children.push(childNode)
  151. }
  152. } else {
  153. const products = productData.filter((product: any) => product.categoryId === category.id)
  154. for (let product of products) {
  155. const productNode = {
  156. id: product.id,
  157. label: product.name,
  158. key: product.key,
  159. is_type: '2', // 2是产品
  160. }
  161. treeNode.children.push(productNode)
  162. }
  163. }
  164. return treeNode
  165. }
  166. const batchdel = () => {
  167. ElMessageBox.confirm(t('message.property.dossier.messages.batchDeleteConfirm'), t('message.property.dossier.messages.tips'), {
  168. confirmButtonText: t('message.property.dossier.messages.confirm'),
  169. cancelButtonText: t('message.property.dossier.messages.cancel'),
  170. type: 'warning',
  171. }).then(async () => {
  172. await device.dev_asset.delete({ deviceKeys: deviceKeys.value })
  173. ElMessage.success(t('message.property.dossier.messages.deleteSuccess'))
  174. getList()
  175. })
  176. }
  177. const del = (row: any) => {
  178. ElMessageBox.confirm(t('message.property.dossier.messages.deleteItemConfirm', { name: row.deviceName }), t('message.property.dossier.messages.tips'), {
  179. confirmButtonText: t('message.property.dossier.messages.confirm'),
  180. cancelButtonText: t('message.property.dossier.messages.cancel'),
  181. type: 'warning',
  182. }).then(async () => {
  183. await device.dev_asset.delete({ deviceKeys: [row.deviceKey] })
  184. ElMessage.success(t('message.property.dossier.messages.deleteSuccess'))
  185. getList()
  186. })
  187. }
  188. // getCateList()
  189. </script>
  190. <style scoped lang="scss">
  191. .custom-tree-node {
  192. width: 100%;
  193. display: flex;
  194. align-items: center;
  195. justify-content: space-between;
  196. font-size: 14px;
  197. padding-right: 8px;
  198. overflow: hidden;
  199. .tree-label {
  200. width: 100%;
  201. overflow: hidden;
  202. text-overflow: ellipsis;
  203. white-space: nowrap;
  204. margin-right: 10px;
  205. }
  206. &:hover {
  207. .tree-options {
  208. display: block;
  209. }
  210. }
  211. }
  212. </style>