Commit f54f2a3aa81a0e21b99a1ea8d6e4b9b684bc7801

Authored by fengwotao
1 parent 2af3fe42

feat:大屏公共接口管理新增批量发布

... ... @@ -104,3 +104,12 @@ export const getCancelPublish = (id) => {
104 104 url: API.DATA_VIEW_INTERFACE + '/cancel_publish/' + id,
105 105 });
106 106 };
  107 +
  108 +//批量发布和取消发布
  109 +export const putPublishOrCancelPublish = (type, ids) => {
  110 + return defHttp.put({
  111 + url: `${API.DATA_VIEW_INTERFACE}/${
  112 + type === 'batchPublish' ? 'batch_publish' : 'batch_cancel_publish'
  113 + }/?ids=${ids.join(',')}`,
  114 + });
  115 +};
... ...
... ... @@ -26,11 +26,18 @@
26 26 />
27 27 </td>
28 28 <td style="width: 12vw">
29   - <a-input
30   - :disabled="item.editDisabled"
31   - placeholder="请输入"
32   - v-model:value="item.value"
33   - />
  29 + <div v-if="item.key === 'fixed_date' || item.key === 'date_range'">
  30 + <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date1" />
  31 + <span>~</span>
  32 + <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date2" />
  33 + </div>
  34 + <div v-else>
  35 + <a-input
  36 + :disabled="item.editDisabled"
  37 + placeholder="请输入"
  38 + v-model:value="item.value"
  39 + />
  40 + </div>
34 41 </td>
35 42 <td style="width: 4vw">
36 43 <a-switch v-model:checked="item.required" />
... ... @@ -82,6 +89,8 @@
82 89 value: string;
83 90 editDisabled: boolean;
84 91 required: boolean;
  92 + date1: string;
  93 + date2: string;
85 94 };
86 95
87 96 const tableArray = reactive<{
... ... @@ -93,6 +102,8 @@
93 102 value: '',
94 103 editDisabled: false,
95 104 required: false,
  105 + date1: '',
  106 + date2: '',
96 107 },
97 108 ],
98 109 });
... ... @@ -104,6 +115,8 @@
104 115 value: '',
105 116 editDisabled: false,
106 117 required: false,
  118 + date1: '',
  119 + date2: '',
107 120 });
108 121 };
109 122
... ... @@ -139,19 +152,39 @@
139 152
140 153 //获取数据
141 154 const getValue = () => {
142   - return tableArray.content;
  155 + const assemblyData = tableArray.content.map((it) => {
  156 + return {
  157 + key: it.key,
  158 + value:
  159 + it.key === 'fixed_date'
  160 + ? `${it.date1},${it.date2}`
  161 + : it.key === 'date_range'
  162 + ? `${it.date1},${it.date2}`
  163 + : it.value,
  164 + editDisabled: it.editDisabled,
  165 + required: it.required,
  166 + };
  167 + });
  168 + return assemblyData;
143 169 };
144 170
145 171 //设置数据
146   - const setValue = (data) => {
147   - nextTick(() => (tableArray.content = data));
148   - nextTick(() =>
149   - setTimeout(() => {
150   - tableArray.content.forEach(() => {
151   - handleChange();
152   - });
153   - }, 20)
154   - );
  172 + const setValue = async (data) => {
  173 + await nextTick();
  174 + const assemblyData = data.map((it) => {
  175 + return {
  176 + key: it.key,
  177 + value: it.value,
  178 + editDisabled: it.editDisabled,
  179 + required: it.required,
  180 + date1: it.key === 'date_range' || it.key === 'fixed_date' ? it.value.split(',').at(-2) : '',
  181 + date2: it.key === 'date_range' || it.key === 'fixed_date' ? it.value.split(',').at(-1) : '',
  182 + };
  183 + });
  184 + tableArray.content = assemblyData;
  185 + tableArray.content.forEach(() => {
  186 + handleChange();
  187 + });
155 188 };
156 189
157 190 //重置数据
... ... @@ -162,6 +195,8 @@
162 195 value: '',
163 196 editDisabled: false,
164 197 required: false,
  198 + date1: '',
  199 + date2: '',
165 200 });
166 201 nextTick(() => {
167 202 tableArray.content.forEach(() => {
... ...
  1 +<!-- eslint-disable vue/valid-v-model -->
1 2 <template>
2 3 <div class="table-content">
  4 + <!-- TODO 待优化 -->
3 5 <table align="center">
4 6 <thead>
5 7 <tr>
... ... @@ -14,7 +16,7 @@
14 16 <td style="width: 1vw">
15 17 {{ index + 1 }}
16 18 </td>
17   - <td style="width: 12vw">
  19 + <td style="width: 8vw">
18 20 <Select
19 21 :disabled="true"
20 22 v-model:value="item.key"
... ... @@ -24,7 +26,7 @@
24 26 allowClear
25 27 />
26 28 </td>
27   - <td style="width: 12vw">
  29 + <td style="width: 8vw">
28 30 <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" />
29 31 <a-tree-select
30 32 v-else-if="item.key === 'organizationId'"
... ... @@ -44,7 +46,6 @@
44 46 notFoundContent="请选择"
45 47 :options="entityOptions"
46 48 allowClear
47   - @change="handleDeviceChange(item)"
48 49 />
49 50 <Select
50 51 v-else-if="item.key === 'keys'"
... ... @@ -54,15 +55,11 @@
54 55 :options="attributeOptions"
55 56 allowClear
56 57 />
57   - <a-range-picker
58   - v-else-if="item.key === 'date'"
59   - v-model:value="item.value"
60   - style="width: 12vw"
61   - :show-time="{ format: 'HH:mm' }"
62   - format="YYYY-MM-DD HH:mm"
63   - :placeholder="['开始', '结束']"
64   - @ok="onRangeOk"
65   - />
  58 + <div v-else-if="item.key === 'fixed_date' || item.key === 'date_range'">
  59 + <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button>
  60 + <span>~</span>
  61 + <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button>
  62 + </div>
66 63 <Select
67 64 v-else
68 65 v-model:value="item.value"
... ... @@ -73,13 +70,31 @@
73 70 @change="handleValueChange(item)"
74 71 />
75 72 </td>
76   - <td style="width: 12vw">
  73 + <td style="width: 8vw">
77 74 <a-input
78 75 :disabled="item.key !== 'scope'"
79 76 placeholder="请输入"
80 77 v-model:value="item.keyValue"
81 78 />
82 79 </td>
  80 + <td style="width: 6vw">
  81 + <a-range-picker
  82 + v-if="item.key === 'fixed_date'"
  83 + style="width: 6vw"
  84 + v-model:value="item.dateValue"
  85 + :show-time="{ format: 'HH:mm' }"
  86 + format="YYYY-MM-DD HH:mm"
  87 + :placeholder="['开始', '结束']"
  88 + />
  89 + <a-range-picker
  90 + v-if="item.key === 'date_range'"
  91 + style="width: 6vw"
  92 + v-model:value="item.dateValue"
  93 + :show-time="{ format: 'HH:mm' }"
  94 + format="YYYY-MM-DD HH:mm"
  95 + :placeholder="['开始', '结束']"
  96 + />
  97 + </td>
83 98 </tr>
84 99 </tbody>
85 100 </table>
... ... @@ -125,6 +140,7 @@
125 140 key: null | string;
126 141 value: null | string;
127 142 keyValue: null | string;
  143 + dateValue: null | string;
128 144 editDisabled: boolean;
129 145 };
130 146
... ... @@ -137,6 +153,7 @@
137 153 value: null,
138 154 keyValue: null,
139 155 editDisabled: false,
  156 + dateValue: null,
140 157 },
141 158 ],
142 159 });
... ... @@ -155,10 +172,6 @@
155 172 getApi(list['x-www-form-urlencoded']);
156 173 };
157 174
158   - const onRangeOk = (value) => {
159   - console.log('onOk: ', value);
160   - };
161   -
162 175 const getApi = (list) => {
163 176 list?.forEach(async (it) => {
164 177 if (it.key === 'deviceProfileId') {
... ... @@ -213,10 +226,6 @@
213 226 }
214 227 };
215 228
216   - const handleDeviceChange = (e) => {
217   - console.log(e);
218   - };
219   -
220 229 //获取数据
221 230 const getValue = () => {
222 231 return tableTestArray.content;
... ... @@ -229,7 +238,7 @@
229 238
230 239 <style scoped lang="less">
231 240 :deep(.ant-select-selector) {
232   - width: 12vw !important;
  241 + width: 7.5vw !important;
233 242 }
234 243 @table-color: #e5e7eb;
235 244
... ...
... ... @@ -102,14 +102,31 @@
102 102
103 103 //获取测试表格的key value 数组对象形式
104 104 const getTestTableKeyValue = () => {
105   - return testEditCellTableRef.value?.getValue().map((it) => {
106   - const value = it.key === 'scope' ? it.keyValue : it.value;
107   - const key = it.key === 'scope' ? it.value : it.key;
108   - return {
109   - key,
110   - value,
111   - };
  105 + //把日期拆分成多个
  106 + const keyValueList = [];
  107 + testEditCellTableRef.value?.getValue()?.forEach((item) => {
  108 + const splitDateKey = item.key === 'date_range' ? item.value?.split(',') : [];
  109 + const splitDateValue = item.key === 'date_range' ? item.dateValue : [];
  110 + for (let i in splitDateKey) {
  111 + const obj = {
  112 + key: splitDateKey[i],
  113 + value: moment(splitDateValue[i]).valueOf(),
  114 + };
  115 + keyValueList.push(obj);
  116 + }
112 117 });
  118 + return testEditCellTableRef.value
  119 + ?.getValue()
  120 + .concat(keyValueList)
  121 + .filter((it) => it.key !== 'date_range' && it.key !== 'fixed_date')
  122 + .map((it) => {
  123 + const value = it.key === 'scope' ? it.keyValue : it.value;
  124 + const key = it.key === 'scope' ? it.value : it.key;
  125 + return {
  126 + key,
  127 + value,
  128 + };
  129 + });
113 130 };
114 131
115 132 //格式化"http:xxxx/api/xx/{xx}/{xx}/{xx}这种格式"
... ... @@ -143,12 +160,6 @@
143 160 Reflect.deleteProperty(params, 'scope');
144 161 Reflect.deleteProperty(params, 'id');
145 162 Reflect.deleteProperty(params, 'type');
146   - if (params['date']) {
147   - Reflect.set(params, 'startTs', moment(params['date'][0]).valueOf());
148   - Reflect.set(params, 'endTs', moment(params['date'][1]).valueOf());
149   - Reflect.deleteProperty(params, 'date');
150   - } else {
151   - }
152 163 return await otherHttp.get(
153 164 { url: api, params },
154 165 {
... ...
... ... @@ -118,15 +118,33 @@ export const schemas: FormSchema[] = [
118 118 },
119 119 },
120 120 {
121   - field: 'requestOriginUrl',
  121 + field: 'originUrlType',
122 122 label: '源地址',
  123 + component: 'ApiSelect',
  124 + required: true,
  125 + colProps: { span: 24 },
  126 + defaultValue: 'server_url',
  127 + componentProps: {
  128 + placeholder: '请选择源地址',
  129 + api: findDictItemByCode,
  130 + params: {
  131 + dictCode: 'dataview_select_origin_type',
  132 + },
  133 + labelField: 'itemText',
  134 + valueField: 'itemValue',
  135 + },
  136 + },
  137 + {
  138 + field: 'requestOriginUrl',
  139 + label: '地址',
123 140 colProps: { span: 24 },
124 141 required: true,
125 142 component: 'Input',
126 143 componentProps: {
127 144 maxLength: 255,
128   - placeholder: '请输入地址',
  145 + placeholder: '请输入地址',
129 146 },
  147 + ifShow: ({ values }) => values['originUrlType'] === 'custom_url',
130 148 },
131 149 {
132 150 field: 'requestHttpType',
... ...
... ... @@ -90,6 +90,9 @@
90 90 ...data.record,
91 91 requestContentType: String(data.record?.requestContentType),
92 92 requestSQLContent: JSON.parse(data.record?.requestParams)?.requestSQLContent?.sql,
  93 + originUrlType: data.record?.requestOriginUrl.startsWith('localhost')
  94 + ? 'server_url'
  95 + : 'custom_url',
93 96 });
94 97 await nextTick(() =>
95 98 setTimeout(() => {
... ... @@ -121,6 +124,8 @@
121 124 const values = await validate();
122 125 if (!values) return;
123 126 const Objects = simpleRequestRef.value?.getValue(true);
  127 + const requestOriginUrl =
  128 + values['originUrlType'] === 'server_url' ? 'localhost' : values['requestOriginUrl'];
124 129 const data = {
125 130 ...values,
126 131 id: !putId.value ? null : putId.value,
... ... @@ -133,6 +138,7 @@
133 138 Body: activeKey.value === 'Body' ? Objects : {},
134 139 Header: activeKey.value === 'Header' ? Objects : {},
135 140 }),
  141 + requestOriginUrl,
136 142 };
137 143 !putId.value ? await saveDataViewInterface(data) : await updateDataViewInterface(data);
138 144 emits('success');
... ...
1 1 <template>
2 2 <div>
3   - <BasicTable @register="registerTable">
  3 + <BasicTable @register="registerTable" :row-selection="rowSelection">
4 4 <template #content="{ record }">
5 5 <a-button type="link" class="ml-2" @click="handleRecordContent(record)"> 查看 </a-button>
6 6 </template>
... ... @@ -14,6 +14,22 @@
14 14 >
15 15 <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
16 16 </Popconfirm>
  17 + <Popconfirm
  18 + title="您确定要批量发布"
  19 + ok-text="确定"
  20 + cancel-text="取消"
  21 + @confirm="handleBatchPublish('batchPublish')"
  22 + >
  23 + <a-button color="error" :disabled="hasBatchPublish"> 批量发布 </a-button>
  24 + </Popconfirm>
  25 + <!-- <Popconfirm
  26 + title="您确定要批量取消发布"
  27 + ok-text="确定"
  28 + cancel-text="取消"
  29 + @confirm="handleBatchPublish('cancelBatchPublish')"
  30 + >
  31 + <a-button color="error" :disabled="hasBatchPublish"> 批量取消发布 </a-button>
  32 + </Popconfirm> -->
17 33 </template>
18 34 <template #action="{ record }">
19 35 <TableAction
... ... @@ -21,7 +37,7 @@
21 37 {
22 38 label: '发布',
23 39 icon: 'ant-design:node-expand-outlined',
24   - onClick: handlePublish.bind(null, record),
  40 + onClick: handlePublish.bind(null, 'publish', record),
25 41 ifShow: () => {
26 42 return record.state === 0;
27 43 },
... ... @@ -29,7 +45,7 @@
29 45 {
30 46 label: '取消发布',
31 47 icon: 'ant-design:node-collapse-outlined',
32   - onClick: handleCancelPublish.bind(null, record),
  48 + onClick: handlePublish.bind(null, 'canelPublish', record),
33 49 ifShow: () => {
34 50 return record.state === 1;
35 51 },
... ... @@ -62,7 +78,7 @@
62 78 <PublicApiForm @register="registerDrawer" @success="handleSuccess" />
63 79 </template>
64 80 <script lang="ts" setup name="list">
65   - import { nextTick, h } from 'vue';
  81 + import { h, ref } from 'vue';
66 82 import { BasicTable, useTable, TableAction } from '/@/components/Table';
67 83 import { useDrawer } from '/@/components/Drawer';
68 84 import { columns, searchFormSchema } from './config';
... ... @@ -72,13 +88,14 @@
72 88 deleteBigViewInterface,
73 89 getPublish,
74 90 getCancelPublish,
  91 + putPublishOrCancelPublish,
75 92 } from '/@/api/bigscreen/center/bigscreenCenter';
76   - import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
77 93 import { Popconfirm, Modal } from 'ant-design-vue';
78 94 import { JsonPreview } from '/@/components/CodeEditor';
79 95 import { useMessage } from '/@/hooks/web/useMessage';
  96 + import { cloneDeep } from 'lodash-es';
80 97
81   - const [registerTable, { reload, setProps }] = useTable({
  98 + const [registerTable, { reload }] = useTable({
82 99 api: getDataViewInterfacePage,
83 100 columns,
84 101 showIndexColumn: false,
... ... @@ -101,19 +118,43 @@
101 118
102 119 const [registerDrawer, { openDrawer }] = useDrawer();
103 120
  121 + const hasBatchPublish = ref(true);
  122 +
  123 + const hasBatchDelete = ref(true);
  124 +
  125 + const batchDeleteIds = ref([]);
  126 +
104 127 const { createMessage } = useMessage();
105 128
106   - const handleSuccess = () => reload();
  129 + const handleSuccess = () => {
  130 + reload();
  131 + setStatusIsTrue();
  132 + };
107 133
108   - const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions } = useBatchDelete(
109   - deleteBigViewInterface,
110   - handleSuccess,
111   - setProps
112   - );
  134 + const setStatusIsFalse = () => {
  135 + hasBatchDelete.value = false;
  136 + hasBatchPublish.value = false;
  137 + };
113 138
114   - nextTick(() => {
115   - setProps(selectionOptions);
116   - });
  139 + const setStatusIsTrue = () => {
  140 + hasBatchDelete.value = true;
  141 + hasBatchPublish.value = true;
  142 + };
  143 +
  144 + const rowSelection = {
  145 + onChange: (_, selectedRows: any[]) => {
  146 + const list = cloneDeep(selectedRows);
  147 + batchDeleteIds.value = list.filter((it) => it.state === 0).map((it) => it.id) as never as any;
  148 + if (batchDeleteIds.value.length > 0) {
  149 + setStatusIsFalse();
  150 + } else {
  151 + setStatusIsTrue();
  152 + }
  153 + },
  154 + getCheckboxProps: (record) => ({
  155 + disabled: record.state === 1,
  156 + }),
  157 + };
117 158
118 159 const handleCreateOrEdit = (record) => {
119 160 const isUpdate = record === null ? false : true;
... ... @@ -132,15 +173,22 @@
132 173 });
133 174 };
134 175
135   - const handlePublish = async (record) => {
136   - await getPublish(record.id);
137   - createMessage.success(`发布成功`);
  176 + const handlePublish = async (type, record) => {
  177 + type === 'publish' ? await getPublish(record.id) : await getCancelPublish(record.id);
  178 + createMessage.success(`${type === 'publish' ? '发布' : '取消发布'}成功`);
  179 + handleSuccess();
  180 + };
  181 +
  182 + const handleBatchPublish = async (type) => {
  183 + await putPublishOrCancelPublish(type, batchDeleteIds.value);
  184 + createMessage.success(`${type === 'batchPublish' ? '批量发布' : '批量取消发布'}成功`);
138 185 handleSuccess();
139 186 };
140 187
141   - const handleCancelPublish = async (record) => {
142   - await getCancelPublish(record.id);
143   - createMessage.success(`取消发布成功`);
  188 + const handleDeleteOrBatchDelete = async (record) => {
  189 + const ids = record === null ? batchDeleteIds.value : [record.id];
  190 + await deleteBigViewInterface(ids);
  191 + createMessage.success(`${record === null ? '批量删除' : '删除'}成功`);
144 192 handleSuccess();
145 193 };
146 194 </script>
... ...