Authored by xwx

license-【无】-license列表和导入

  1 +<div>
  2 + <!-- 表格-->
  3 + <el-table :border="showBorder" :data="dataList" :default-expand-all="defaultExpand" :expand-row-keys="expands"
  4 + :height="height" :row-key="getRowKeys" :size="size" @select="handleSelect"
  5 + @select-all="handleSelectAll"
  6 + @selection-change="handleSelectionChange" header-row-class-name="tbl-header-class" ref="multipleTable"
  7 + stripe
  8 + style="width: 100%;margin: 0px 0px; font-size:13.5px;" v-loading="loading"
  9 + >
  10 +
  11 + <el-table-column type="expand" v-if="showExpand">
  12 + <template #default="scope">
  13 + <slot :scope="scope" name="expand">
  14 +
  15 + </slot>
  16 + </template>
  17 + </el-table-column>
  18 + <el-table-column align="center" type="selection" v-if="showSelection && columns.length > 0" width="55"/>
  19 + <el-table-column :label="indexLabel" align="center" type="index" v-if="showIndex && columns.length > 0"
  20 + width="50"/>
  21 +
  22 + <el-table-column :align="item.align == undefined ? 'center' : item.align " :label="item.label" :prop="item.prop"
  23 + :sortable="item.sortable == undefined ? false : item.sortable"
  24 + :width="getWidth(item.width)"
  25 + v-for="item in columns">
  26 + <template v-if="!item.columns || item.columns.lendth==0" #default="scope">
  27 + <slot :column="item" :prop="item.prop" :row="scope.row">
  28 + <div v-if="typeof(item.click) == 'function' && typeof(item.render) == 'function'">
  29 + <span @click="item.click(scope.row)" style="cursor: pointer"
  30 + v-html="item.render(scope.row)"></span>
  31 + </div>
  32 + <div v-else-if="typeof(item.click) == 'function'">
  33 + <span @click="item.click(scope.row)" style="cursor: pointer"> {{scope.row[item.prop]}}</span>
  34 + </div>
  35 + <div v-else-if="typeof(item.render) == 'function'">
  36 + <span v-html="item.render(scope.row)">{{scope.row[item.prop]}}</span>
  37 + </div>
  38 +
  39 + <span v-else>
  40 + <el-tooltip placement="top">
  41 + <template #content>
  42 + <div v-html="getTextContent(scope.row[item.prop])">
  43 + </div>
  44 + </template>
  45 + <div style="overflow: hidden; text-overflow: ellipsis;display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;">
  46 + {{scope.row[item.prop]}}
  47 + </div>
  48 + </el-tooltip>
  49 + </span>
  50 + </slot>
  51 + </template>
  52 + <el-table-column v-else :align="columnItem.align == undefined ? 'center' : columnItem.align " :label="columnItem.label" :prop="columnItem.prop"
  53 + :sortable="columnItem.sortable == undefined ? false : columnItem.sortable"
  54 + :width="getWidth(columnItem.width)"
  55 + v-for="columnItem in item.columns">
  56 + <template #default="scope">
  57 + <slot :column="columnItem" :prop="columnItem.prop" :row="scope.row">
  58 + <div v-if="typeof(columnItem.click) == 'function' && typeof(columnItem.render) == 'function'">
  59 + <span @click="columnItem.click(scope.row)" style="cursor: pointer"
  60 + v-html="columnItem.render(scope.row)"></span>
  61 + </div>
  62 + <div v-else-if="typeof(columnItem.click) == 'function'">
  63 + <span @click="columnItem.click(scope.row)" style="cursor: pointer"> {{scope.row[columnItem.prop]}}</span>
  64 + </div>
  65 + <div v-else-if="typeof(columnItem.render) == 'function'">
  66 + <span v-html="columnItem.render(scope.row)">{{scope.row[columnItem.prop]}}</span>
  67 + </div>
  68 +
  69 + <span v-else>
  70 + <el-tooltip placement="top">
  71 + <template #content>
  72 + <div v-html="getTextContent(scope.row[columnItem.prop])">
  73 + </div>
  74 + </template>
  75 + <div style="overflow: hidden; text-overflow: ellipsis;display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;">
  76 + {{scope.row[columnItem.prop]}}
  77 + </div>
  78 + </el-tooltip>
  79 + </span>
  80 + </slot>
  81 + </template>
  82 + </el-table-column>
  83 + </el-table-column>
  84 +
  85 + <el-table-column align="center" label="操作" v-if="showTools && columns.length > 0" width="80">
  86 + <template #default="scope">
  87 + <slot :scope="scope" name="tools"></slot>
  88 + </template>
  89 + </el-table-column>
  90 + </el-table>
  91 + <!-- 分页 -->
  92 + <div style='text-align: left;background-color: white' v-if="showPage">
  93 + <el-pagination
  94 + :current-page="currentPage"
  95 + :layout="layout"
  96 + :page-size="pageSize"
  97 + :page-sizes="pageSizes"
  98 + :total="total"
  99 + @current-change="handleCurrentChange"
  100 + @next-click="nextPage"
  101 + @prev-click="prePage"
  102 + @size-change="handleSizeChange">
  103 + </el-pagination>
  104 + </div>
  105 +</div>
  106 +
  1 +/**
  2 + * 分页表格组件
  3 + */
  4 +export default {
  5 + name: 'tablePageColumnIndex',
  6 + template: '',
  7 + components: {},
  8 + props: {
  9 + // 展示分页
  10 + showPage: {
  11 + type: Boolean,
  12 + default: true
  13 + },
  14 + showBorder: {
  15 + type: Boolean,
  16 + default: true
  17 + },
  18 + // 高度
  19 + height: {
  20 + type: Number,
  21 + default: window.innerHeight
  22 + },
  23 + // 展示下标
  24 + showIndex: {
  25 + type: Boolean,
  26 + default: true
  27 + },
  28 + showSelection: {
  29 + type: Boolean,
  30 + default: false
  31 + },
  32 + indexLabel: {
  33 + type: String,
  34 + default: '序号'
  35 + },
  36 + // 分页页码设置
  37 + pageSizes: {
  38 + type: Array,
  39 + default: [10, 50, 100, 200, 300, 400]
  40 + },
  41 + // 默认展示
  42 + pageSize: {
  43 + type: Number,
  44 + default: 10
  45 + },
  46 + // 总数
  47 + total: {
  48 + type: Number,
  49 + default: 0
  50 + },
  51 + // 展示组件
  52 + layout: {
  53 + type: String,
  54 + // Start Wang 2022/1/19 14:22 上一页和下一页切花不生效,暂无解决办法
  55 + //default: "total, prev,pager,next, sizes, jumper"
  56 + default: "total, pager,sizes, jumper"
  57 + // End Wang 2022/1/19 14:22
  58 + },
  59 + // 列
  60 + columns: {
  61 + type: Array,
  62 + default: []
  63 + },
  64 + // 数据
  65 + dataList: {
  66 + type: Array,
  67 + default: []
  68 + },
  69 + // 是否展示加载
  70 + loading: {
  71 + type: Boolean,
  72 + default: false
  73 + },
  74 + maxWidth: {
  75 + type: Number,
  76 + default: window.innerWidth
  77 + },
  78 + showTools: {
  79 + type: Boolean,
  80 + default: false
  81 + },
  82 + // medium / small / mini
  83 + size: {
  84 + type: String,
  85 + default: 'small'
  86 + },
  87 + multipleSelection: {
  88 + type: Array,
  89 + default: []
  90 + },
  91 + //展开行
  92 + showExpand: {
  93 + type: Boolean,
  94 + default: false
  95 + },
  96 + //行数据的key
  97 + getRowKeys: {
  98 + type: String,
  99 + default: 'id'
  100 + },
  101 + //默认展开哪行
  102 + expands: {
  103 + type: Array,
  104 + default: []
  105 + },
  106 + //是否默认展开所有行
  107 + defaultExpand: {
  108 + type: Boolean,
  109 + default: false
  110 + }
  111 + },
  112 + data() {
  113 + return {}
  114 + },
  115 + setup(props, {attrs, slots, emit}) {
  116 + const {proxy} = Vue.getCurrentInstance();
  117 + let currentPage = Vue.ref(1);
  118 + let pageSize = Vue.ref(props.pageSize);
  119 + // let multipleSelection=Vue.ref([]);
  120 +
  121 + /**
  122 + * 获取宽度
  123 + * <p>
  124 + * 作者: Wang
  125 + * 时间:2021/11/16 16:19
  126 + */
  127 +
  128 + let getWidth = (width) => {
  129 + let maxWidth = (function () {
  130 + let cols = props.columns;
  131 + if (cols && cols.length > 0) {
  132 + // 求和
  133 + let w = 0;
  134 + cols.forEach(function (v) {
  135 + w += parseFloat(v.width);
  136 + })
  137 +
  138 + let max = props.maxWidth;
  139 + if (props.showTools) {
  140 + max -= 80;
  141 + }
  142 +
  143 + if (w < max) {
  144 + return max / w * width;
  145 + }
  146 + }
  147 + return width;
  148 + })();
  149 +
  150 + return maxWidth;
  151 + }
  152 +
  153 +
  154 + let callback = () => {
  155 + let params = {
  156 + page: currentPage.value, limit: pageSize.value
  157 + }
  158 + proxy.$refs.multipleTable.clearSelection();
  159 +
  160 + emit('loaddata', params)
  161 + }
  162 +
  163 + // 每页展示多少条
  164 + let handleSizeChange = (val) => {
  165 + // Start Wang 2021/12/15 23:46 切换页码重置初始页
  166 + currentPage.value = 1
  167 + // End Wang 2021/12/15 23:46 切换页码重置初始页
  168 + // console.log(`每页 ${val} 条`)
  169 + //props.pageSize = val;
  170 + pageSize.value = val;
  171 + callback();
  172 + }
  173 +
  174 + // 切换页码
  175 + let handleCurrentChange = (val) => {
  176 + // console.log(`当前页: ${val}`)
  177 + //props.currentPage = val;
  178 + currentPage.value = val;
  179 + callback();
  180 + }
  181 +
  182 + // 切换页码
  183 + let prePage = (val) => {
  184 + // console.log(`当前页: ${val}`)
  185 + // props.currentPage = val - 1;
  186 + currentPage.value = val - 1;
  187 + callback();
  188 + }
  189 +
  190 + // 切换页码
  191 + let nextPage = (val) => {
  192 + // console.log(`当前页: ${val}`)
  193 + // props.currentPage = val + 1;
  194 + currentPage.value = val + 1;
  195 + callback();
  196 + }
  197 +
  198 + // 监听编辑状态
  199 + // Vue.watch(() => filterText.value, (newValue, oldVlaue) => {
  200 + // proxy.$refs.tree.filter(newValue)
  201 + // });
  202 +
  203 + //全选事件
  204 + let handleSelectionChange = (val) => {
  205 + // multipleSelection.value = val
  206 + emit('selectionChange', val)
  207 +
  208 + }
  209 + //设置默认选中
  210 + let toggleSelection = (rows) => {
  211 + //console.log("rows",rows)
  212 + proxy.$nextTick(function () {
  213 + //console.log("set",props.dataList,props.multipleSelection)
  214 +
  215 + if (rows) {
  216 + rows.forEach(row => {
  217 + //设置该表格选框选中
  218 + proxy.$refs.multipleTable.toggleRowSelection(row);
  219 + });
  220 + } else {
  221 + proxy.$refs.multipleTable.clearSelection();
  222 + }
  223 + })
  224 + }
  225 +
  226 + let getTextContent = (val) => {
  227 + if (val && val != '' && val != null) {
  228 + val = val + ''.replace(/[^\x00-\xff]/g, "$&\x01").replace(/.{50}\x01?/g, "$&<br/>").replace(/\x01/g, "");
  229 + }
  230 + return val;
  231 +
  232 + }
  233 + //设置父节点选中后children也选中
  234 + let setChecked = (row) => {
  235 + let arr = [];
  236 + if (row.children) {
  237 + row.children.map(j => {
  238 + arr.push(j)
  239 + setChecked(j)
  240 + })
  241 + }
  242 + toggleSelection(arr)
  243 + }
  244 + //勾选数据行的Checkbox事件
  245 + let handleSelect = (selection, row) => {
  246 + setChecked(row);
  247 +
  248 + emit('handleSelect', selection)
  249 + }
  250 + //勾选全选checkbox事件
  251 + let handleSelectAll = (selection) => {
  252 + const isSelect = selection.some(el => {
  253 + const tableDataIds = props.dataList.map(j => j[props.getRowKeys])
  254 + return tableDataIds.includes(el.id)
  255 + })
  256 + const isCancel = !props.dataList.every(el => {
  257 + const selectIds = selection.map(j => j[props.getRowKeys])
  258 + return selectIds.includes(el.id)
  259 + })
  260 + if (isSelect) {
  261 + setChecked(selection);
  262 + }
  263 + if (isCancel) {
  264 + props.dataList.map(el => {
  265 + setChecked(el);
  266 + })
  267 + }
  268 +
  269 + emit('handleSelectAll', selection)
  270 + }
  271 + // 挂载完
  272 + Vue.onMounted(() => {
  273 + //callback();
  274 +
  275 + })
  276 + Vue.watch(() => props.dataList, (newValue, oldValue) => {
  277 + setTimeout(function () {
  278 + if (props.showSelection) {
  279 + toggleSelection(props.multipleSelection)
  280 + }
  281 + }, 100)
  282 +
  283 +
  284 + })
  285 +
  286 + return {
  287 + handleSelect,
  288 + handleSelectAll,
  289 + toggleSelection,
  290 + handleSelectionChange,
  291 + // multipleSelection,
  292 + currentPage,
  293 + pageSize,
  294 + handleSizeChange,
  295 + handleCurrentChange,
  296 + prePage,
  297 + nextPage,
  298 + getWidth,
  299 + getTextContent
  300 + }
  301 + }
  302 +}
@@ -6,7 +6,6 @@ @@ -6,7 +6,6 @@
6 <el-form-item> 6 <el-form-item>
7 <el-upload 7 <el-upload
8 :auto-upload="true" 8 :auto-upload="true"
9 - :before-upload="beforeAvatarUpload"  
10 :http-request="getFile" 9 :http-request="getFile"
11 :multiple="false" 10 :multiple="false"
12 :show-file-list="false" 11 :show-file-list="false"
@@ -36,8 +35,8 @@ @@ -36,8 +35,8 @@
36 <el-row> 35 <el-row>
37 <el-col :span="24" style="text-align: left;padding: 10px 0;font-size: 16px;font-weight: bold;">授权详情</el-col> 36 <el-col :span="24" style="text-align: left;padding: 10px 0;font-size: 16px;font-weight: bold;">授权详情</el-col>
38 </el-row> 37 </el-row>
39 - <cm-table-page :columns="tableData.columns" :dataList="tableData.dataList"  
40 - :height="200" 38 + <cm-table-page-column :columns="tableData.columns" :dataList="tableData.dataList"
  39 + :height="300"
41 :loading="false" 40 :loading="false"
42 :showBorder="true" 41 :showBorder="true"
43 :showIndex="false" 42 :showIndex="false"
@@ -46,27 +45,47 @@ @@ -46,27 +45,47 @@
46 :showTools="false" 45 :showTools="false"
47 > 46 >
48 <template #default="{row,prop,column}"> 47 <template #default="{row,prop,column}">
49 - <div v-if="prop == 'resNum'">  
50 -<!-- <span class="" style="color:#1e9fff;text-decoration: underline;cursor: pointer;">{{row.resNum }}</span>-->  
51 - <span :style="{'color':row.resNum>=1000?'red':''}">{{row.resNum}}</span>  
52 - </div>  
53 - <div v-else>  
54 - {{row[prop]}} 48 + <div v-if="row.usage == '已使用'">
  49 + <span v-if="prop == 'resNum'" :style="{'color':tableData.dataList[1].resNum>=tableData.dataList[0].resNum?'red':''}">{{row.resNum}}</span>
  50 + <span v-if="prop != 'resNum'">
  51 + {{row[prop]}}
  52 + </span>
55 <el-tooltip 53 <el-tooltip
56 effect="dark" 54 effect="dark"
57 placement="bottom" 55 placement="bottom"
58 > 56 >
59 <template #content> 57 <template #content>
60 <div> 58 <div>
61 - <span>该协议写包含</span> 59 + <span>已使用资源数量大于授权数量,请及时更新liscense</span>
62 <span style="word-break: break-all;">{{splitDetail(prop)}}</span> 60 <span style="word-break: break-all;">{{splitDetail(prop)}}</span>
63 </div> 61 </div>
64 </template> 62 </template>
65 <i v-if="row[prop] && prop !='usage'" style="margin-left:6px;" class="el-icon-info"></i> 63 <i v-if="row[prop] && prop !='usage'" style="margin-left:6px;" class="el-icon-info"></i>
66 </el-tooltip> 64 </el-tooltip>
67 </div> 65 </div>
  66 + <div v-else>
  67 + <div v-if="row[prop] != null && row[prop] != ''">
  68 + <span>
  69 + {{row[prop]}}
  70 + </span>
  71 + </div>
  72 + <div v-else>
  73 + <span>
  74 + -
  75 + </span>
  76 + <el-tooltip
  77 + effect="dark"
  78 + placement="bottom"
  79 + >
  80 + <template #content>
  81 + <span>当前协议可以无限绑定采集资源</span>
  82 + </template>
  83 + <i v-if="prop !='usage'" style="margin-left:6px;" class="el-icon-info"></i>
  84 + </el-tooltip>
  85 + </div>
  86 + </div>
68 </template> 87 </template>
69 - </cm-table-page> 88 + </cm-table-page-column>
70 </div> 89 </div>
71 </div> 90 </div>
72 </div> 91 </div>
@@ -81,49 +81,49 @@ export default { @@ -81,49 +81,49 @@ export default {
81 let getLicenseColumn=()=>{ 81 let getLicenseColumn=()=>{
82 cateColumn.value=[ 82 cateColumn.value=[
83 { 83 {
84 - prop: 'SSH', 84 + prop: 'ssh',
85 label: 'SSH', 85 label: 'SSH',
86 sortable: true, 86 sortable: true,
87 align: 'center', 87 align: 'center',
88 }, 88 },
89 { 89 {
90 - prop: 'SNMP', 90 + prop: 'snmp',
91 label: 'SNMP', 91 label: 'SNMP',
92 sortable: true, 92 sortable: true,
93 align: 'center', 93 align: 'center',
94 }, 94 },
95 { 95 {
96 - prop: 'SDK', 96 + prop: 'sdk',
97 label: 'SDK', 97 label: 'SDK',
98 sortable: true, 98 sortable: true,
99 align: 'center', 99 align: 'center',
100 }, 100 },
101 { 101 {
102 - prop: 'DB', 102 + prop: 'db',
103 label: 'DB', 103 label: 'DB',
104 sortable: true, 104 sortable: true,
105 align: 'center', 105 align: 'center',
106 }, 106 },
107 { 107 {
108 - prop: 'JMX', 108 + prop: 'jmx',
109 label: 'JMX', 109 label: 'JMX',
110 sortable: true, 110 sortable: true,
111 align: 'center', 111 align: 'center',
112 }, 112 },
113 { 113 {
114 - prop: 'SYSLOG', 114 + prop: 'syslog',
115 label: 'SYSLOG', 115 label: 'SYSLOG',
116 sortable: true, 116 sortable: true,
117 align: 'center', 117 align: 'center',
118 }, 118 },
119 { 119 {
120 - prop: 'HTTP', 120 + prop: 'http',
121 label: 'HTTP', 121 label: 'HTTP',
122 sortable: true, 122 sortable: true,
123 align: 'center', 123 align: 'center',
124 }, 124 },
125 { 125 {
126 - prop: 'IPMI', 126 + prop: 'ipmi',
127 label: 'IPMI', 127 label: 'IPMI',
128 sortable: true, 128 sortable: true,
129 align: 'center', 129 align: 'center',
@@ -131,37 +131,21 @@ export default { @@ -131,37 +131,21 @@ export default {
131 ] 131 ]
132 tableData.value.columns.map(item=>{ 132 tableData.value.columns.map(item=>{
133 if(item.prop=='protocolCate'){ 133 if(item.prop=='protocolCate'){
134 - item.columns=cateColumn.value 134 + item.columns=cateColumn.value;
135 } 135 }
136 }) 136 })
137 } 137 }
138 - //给列表数据追加相关的详细协议  
139 // 获取列表 138 // 获取列表
140 let getDataList = () => { 139 let getDataList = () => {
141 - tableData.value.dataList = [  
142 - {usage:'授权数量',resNum:'2',SSH:'12'},  
143 - {usage:'剩余数量',resNum:'1000',SNMP:'1',HTTP:'23'},  
144 - ];  
145 -  
146 - return  
147 -  
148 - let params = {  
149 - page: search.value.page,  
150 - limit: search.value.limit,  
151 - }  
152 -  
153 - proxy.$http.list(`/license/list`, params, function (res) {  
154 - if (res && res.object) {  
155 - let dataList = res.object.content;  
156 - let arr = [];  
157 - dataList.map(item => {  
158 - arr.push(item[0])  
159 - })  
160 - tableData.value.dataList = arr;  
161 - tableData.value.count = parseInt(res.object.total); 140 + proxy.$http.get(`/api-web/license/getList`, {}, function (res) {
  141 + if (res && res.success) {
  142 + let dataList = res.object;
  143 + dataList.license.usage='已授权';
  144 + dataList.local.usage='已使用';
  145 + tableData.value.dataList[0] = dataList.license;
  146 + tableData.value.dataList[1] = dataList.local;
162 } else { 147 } else {
163 tableData.value.dataList = []; 148 tableData.value.dataList = [];
164 - tableData.value.count = 0;  
165 } 149 }
166 }); 150 });
167 } 151 }
@@ -181,44 +165,19 @@ export default { @@ -181,44 +165,19 @@ export default {
181 return str; 165 return str;
182 } 166 }
183 167
184 - // 下载license  
185 - let handleDownLoad=(row)=>{  
186 - proxy.$global.confirm("确定下载license?", function () {  
187 - proxy.$http.downloadFile("/api-web/export", row);  
188 168
189 - })  
190 - }  
191 -  
192 - let beforeAvatarUpload = (file) => {  
193 - const isJPG = file.type.indexOf('image/') != -1  
194 - if (!isJPG) {  
195 - proxy.$global.showMsg('您上传的不是图片文件,请选择图片!', 'error');  
196 - }  
197 - return isJPG  
198 - }  
199 let getFile = (param) => { 169 let getFile = (param) => {
200 let fileObj = param.file 170 let fileObj = param.file
201 let params = { 171 let params = {
202 file: fileObj, 172 file: fileObj,
203 - code: param.data  
204 } 173 }
205 // 上传文件 174 // 上传文件
206 - proxy.$http.uploadFile("/api-u/sysConf/uploadFile", params, function (res) { 175 + proxy.$http.uploadFile("/api-web/license/uploadZip", params, function (res) {
207 if (res && res.success) { 176 if (res && res.success) {
208 proxy.$global.showMsg("上传成功!"); 177 proxy.$global.showMsg("上传成功!");
209 } 178 }
210 }) 179 })
211 } 180 }
212 - //获取license详情  
213 - let getLicenseDetail=()=>{  
214 - let params={}  
215 - proxy.$http.get(`/license/selectById`, params, function (res) {  
216 - if (res && res.object) {  
217 - let dataList = res.object.content;  
218 -  
219 - }  
220 - });  
221 - }  
222 181
223 // 挂载完 182 // 挂载完
224 Vue.onMounted(() => { 183 Vue.onMounted(() => {
@@ -229,13 +188,11 @@ export default { @@ -229,13 +188,11 @@ export default {
229 188
230 return { 189 return {
231 isExport, 190 isExport,
232 - beforeAvatarUpload,  
233 getFile, 191 getFile,
234 licenseCateData, 192 licenseCateData,
235 getLicenseColumn, 193 getLicenseColumn,
236 cateColumn, 194 cateColumn,
237 splitDetail, 195 splitDetail,
238 - handleDownLoad,  
239 height, 196 height,
240 tableData, 197 tableData,
241 getDataList, 198 getDataList,