Skip to content

Commit 62e6346

Browse files
committed
feat(CRUD):新增可选的历史记录云备份功能
1 parent 6c8b9f5 commit 62e6346

File tree

10 files changed

+683
-47
lines changed

10 files changed

+683
-47
lines changed

app/admin/controller/crud/Crud.php

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class Crud extends Backend
6060
*/
6161
protected array $dtStringToArray = ['checkbox', 'selects', 'remoteSelects', 'city', 'images', 'files'];
6262

63-
protected array $noNeedPermission = ['logStart', 'getFileData', 'parseFieldData', 'generateCheck'];
63+
protected array $noNeedPermission = ['logStart', 'getFileData', 'parseFieldData', 'generateCheck', 'uploadCompleted'];
6464

6565
public function initialize(): void
6666
{
@@ -294,7 +294,9 @@ public function generate(): void
294294
$this->error($e->getMessage());
295295
}
296296

297-
$this->success();
297+
$this->success('', [
298+
'crudLog' => CrudLog::find($crudLogId),
299+
]);
298300
}
299301

300302
/**
@@ -304,8 +306,41 @@ public function generate(): void
304306
public function logStart(): void
305307
{
306308
$id = $this->request->post('id');
307-
$info = CrudLog::find($id)->toArray();
308-
if (!$info) {
309+
$type = $this->request->post('type', '');
310+
311+
if ($type == 'Cloud history') {
312+
// 云端 历史记录
313+
$client = get_ba_client();
314+
$response = $client->request('GET', '/api/v6.Crud/info', [
315+
'query' => [
316+
'id' => $id,
317+
'server' => 1,
318+
'ba-user-token' => $this->request->post('token', ''),
319+
]
320+
]);
321+
$body = $response->getBody();
322+
$statusCode = $response->getStatusCode();
323+
$content = $body->getContents();
324+
if ($content == '' || stripos($content, '<title>系统发生错误</title>') !== false || $statusCode != 200) {
325+
$this->error(__('Failed to load cloud data'));
326+
}
327+
$json = json_decode($content, true);
328+
if (json_last_error() != JSON_ERROR_NONE) {
329+
$this->error(__('Failed to load cloud data'));
330+
}
331+
if (is_array($json)) {
332+
if ($json['code'] != 1) {
333+
$this->error($json['msg']);
334+
}
335+
336+
$info = $json['data']['info'];
337+
}
338+
} else {
339+
// 本地记录
340+
$info = CrudLog::find($id)->toArray();
341+
}
342+
343+
if (!isset($info) || !$info) {
309344
$this->error(__('Record not found'));
310345
}
311346

@@ -328,6 +363,7 @@ public function logStart(): void
328363
$this->success('', [
329364
'table' => $info['table'],
330365
'fields' => $info['fields'],
366+
'sync' => $info['sync'],
331367
]);
332368
}
333369

@@ -548,6 +584,38 @@ public function generateCheck(): void
548584
$this->success();
549585
}
550586

587+
/**
588+
* CRUD 设计记录上传成功标记
589+
* @throws Throwable
590+
*/
591+
public function uploadCompleted(): void
592+
{
593+
$syncIds = $this->request->post('syncIds/a', []);
594+
$cancelSync = $this->request->post('cancelSync/b', false);
595+
$crudLogModel = new CrudLog();
596+
597+
if ($cancelSync) {
598+
$logData = $crudLogModel->where('id', 'in', array_keys($syncIds))->select();
599+
foreach ($logData as $logDatum) {
600+
if ($logDatum->sync == $syncIds[$logDatum->id]) {
601+
$logDatum->sync = 0;
602+
$logDatum->save();
603+
}
604+
}
605+
$this->success();
606+
}
607+
608+
$saveData = [];
609+
foreach ($syncIds as $key => $syncId) {
610+
$saveData[] = [
611+
'id' => $key,
612+
'sync' => $syncId,
613+
];
614+
}
615+
$crudLogModel->saveAll($saveData);
616+
$this->success();
617+
}
618+
551619
/**
552620
* 关联表数据解析
553621
* @param $field

app/admin/lang/zh-cn/crud/crud.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
'del-field fail not exist' => '字段 %s 删除失败,数据表内不存在该字段',
88
'change-field-attr fail not exist' => '修改字段 %s 的属性失败,数据表内不存在该字段',
99
'add-field fail exist' => '添加字段 %s 失败,数据表内已经存在该字段',
10+
'Failed to load cloud data' => '加载云端数据失败,请稍后重试!',
1011
];

web/src/api/backend/crud.ts

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { useBaAccount } from '/@/stores/baAccount'
2+
import { useSiteConfig } from '/@/stores/siteConfig'
13
import createAxios from '/@/utils/axios'
24

35
export const url = '/admin/crud.Crud/'
@@ -47,13 +49,21 @@ export function parseFieldData(data: anyObj) {
4749
})
4850
}
4951

50-
export function postLogStart(id: number) {
52+
export function postLogStart(id: string, type: string) {
53+
const data: anyObj = {
54+
id,
55+
type,
56+
}
57+
58+
if (type == 'Cloud history') {
59+
const baAccount = useBaAccount()
60+
data['token'] = baAccount.getToken('auth')
61+
}
62+
5163
return createAxios({
5264
url: url + 'logStart',
5365
method: 'post',
54-
data: {
55-
id: id,
56-
},
66+
data: data,
5767
})
5868
}
5969

@@ -77,3 +87,44 @@ export function checkCrudLog(table: string, connection: string) {
7787
},
7888
})
7989
}
90+
91+
export function uploadLog(data: anyObj) {
92+
const baAccount = useBaAccount()
93+
const siteConfig = useSiteConfig()
94+
data['ba-user-token'] = baAccount.getToken('auth')
95+
return createAxios({
96+
url: siteConfig.apiUrl + '/api/v6.Crud/uploadLog',
97+
data: data,
98+
method: 'post',
99+
})
100+
}
101+
102+
export function uploadCompleted(data: anyObj) {
103+
return createAxios({
104+
url: url + 'uploadCompleted',
105+
data: data,
106+
method: 'post',
107+
})
108+
}
109+
110+
export function logs(data: anyObj = {}) {
111+
const baAccount = useBaAccount()
112+
const siteConfig = useSiteConfig()
113+
data['ba-user-token'] = baAccount.getToken('auth')
114+
return createAxios({
115+
url: siteConfig.apiUrl + '/api/v6.Crud/logs',
116+
data: data,
117+
method: 'post',
118+
})
119+
}
120+
121+
export function delLog(data: anyObj = {}) {
122+
const baAccount = useBaAccount()
123+
const siteConfig = useSiteConfig()
124+
data['ba-user-token'] = baAccount.getToken('auth')
125+
return createAxios({
126+
url: siteConfig.apiUrl + '/api/v6.Crud/del',
127+
data: data,
128+
method: 'post',
129+
})
130+
}

web/src/lang/backend/en/crud/log.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ export default {
44
comment: 'comment',
55
table: 'table',
66
fields: 'fields',
7+
sync: 'sync',
8+
'sync no': 'no',
9+
'sync yes': 'yes',
710
status: 'status',
811
delete: 'delete code',
912
'status delete': 'status delete',
@@ -12,4 +15,39 @@ export default {
1215
'status start': 'status start',
1316
create_time: 'create_time',
1417
'quick Search Fields': 'id,table_name,comment',
18+
'Upload the selected design records to the cloud for cross-device use': 'Upload the selected design records to the cloud for cross-device use',
19+
'Design records that have been synchronized to the cloud': 'Design records that have been synchronized to the cloud',
20+
'Cloud record': 'Cloud record',
21+
Settings: 'Settings',
22+
'Login for backup design': 'Login for backup design',
23+
'CRUD design record synchronization scheme': 'CRUD design record synchronization scheme',
24+
Manual: 'Manual',
25+
automatic: 'automatic',
26+
'When automatically synchronizing records, share them to the open source community':
27+
'When automatically synchronizing records, share them to the open source community',
28+
'Not to share': 'Not to share',
29+
Share: 'Share',
30+
'Enabling sharing can automatically earn community points during development':
31+
'Enabling sharing can automatically earn community points during development',
32+
'The synchronized CRUD records are automatically resynchronized when they are updated':
33+
'The synchronized CRUD records are automatically resynchronized when they are updated',
34+
'Do not resynchronize': 'Do not resynchronize',
35+
'Automatic resynchronization': 'Automatic resynchronization',
36+
'No effective design': 'No effective design',
37+
'Number of fields': 'Number of fields',
38+
'Upload type': 'Upload type',
39+
Update: 'Update',
40+
'New added': 'New added',
41+
'Share to earn points': 'Share to earn points',
42+
'Share to the open source community': 'Share to the open source community',
43+
'No design record': 'No design record',
44+
Field: 'Field',
45+
'Field information': 'Field information',
46+
'No field': 'No field',
47+
'Field name': 'Field name',
48+
Note: 'Note',
49+
Type: 'Type',
50+
Load: 'Load',
51+
'Delete cloud records?': 'Delete cloud records?',
52+
'You can use the synchronized design records across devices': 'You can use the synchronized design records across devices',
1553
}

web/src/lang/backend/zh-cn/crud/log.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ export default {
44
comment: '表注释',
55
table: '数据表数据',
66
fields: '字段数据',
7+
sync: '是否上传',
8+
'sync no': '否',
9+
'sync yes': '是',
710
status: '状态',
811
delete: '删除代码',
912
'status delete': '代码已删除',
@@ -12,4 +15,37 @@ export default {
1215
'status start': '生成中',
1316
create_time: '创建时间',
1417
'quick Search Fields': 'ID、表名、注释',
18+
'Upload the selected design records to the cloud for cross-device use': '上传选中的设计记录至云端以跨设备使用',
19+
'Design records that have been synchronized to the cloud': '已同步至云端的设计记录',
20+
'Cloud record': '云记录',
21+
Settings: '设置',
22+
'Login for backup design': '登录以备份设计',
23+
'CRUD design record synchronization scheme': 'CRUD 设计记录同步方案',
24+
Manual: '手动',
25+
automatic: '自动',
26+
'When automatically synchronizing records, share them to the open source community': '自动同步记录时分享至开源社区',
27+
'Not to share': '不分享',
28+
Share: '分享',
29+
'Enabling sharing can automatically earn community points during development': '开启分享可于开发同时自动获取社区积分',
30+
'The synchronized CRUD records are automatically resynchronized when they are updated': '已同步的 CRUD 记录被更新时自动重新同步',
31+
'Do not resynchronize': '不重新同步',
32+
'Automatic resynchronization': '自动重新同步',
33+
'No effective design': '无有效设计',
34+
'Number of fields': '字段数',
35+
'Upload type': '上传类型',
36+
Update: '更新',
37+
'New added': '新增',
38+
'Share to earn points': '分享获得积分',
39+
'Share to the open source community': '分享至开源社区',
40+
'No design record': '无设计记录',
41+
Field: '字段',
42+
'Field information': '字段信息',
43+
'No field': '无字段',
44+
'Field name': '字段名',
45+
Note: '注释',
46+
Type: '类型',
47+
Load: '载入',
48+
'Delete cloud records?': '删除云端记录?',
49+
'You can use the synchronized design records across devices':
50+
'您可以跨设备使用已同步的设计记录;选择手动同步时,系统不会主动收集任何数据,同时系统永远不会同步表内数据',
1551
}

web/src/stores/config.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineStore } from 'pinia'
22
import { reactive } from 'vue'
33
import { STORE_CONFIG } from '/@/stores/constant/cacheKey'
4-
import type { Lang, Layout } from '/@/stores/interface'
4+
import type { Crud, Lang, Layout } from '/@/stores/interface'
55

66
export const useConfig = defineStore(
77
'config',
@@ -43,6 +43,12 @@ export const useConfig = defineStore(
4343
],
4444
})
4545

46+
const crud: Crud = reactive({
47+
syncType: 'manual',
48+
syncedUpdate: 'yes',
49+
syncAutoPublic: 'no',
50+
})
51+
4652
function menuWidth() {
4753
if (layout.shrink) {
4854
return layout.menuCollapse ? '0px' : layout.menuWidth + 'px'
@@ -79,7 +85,7 @@ export const useConfig = defineStore(
7985
}
8086

8187
const setLayout = (name: keyof Layout, value: any) => {
82-
layout[name] = value as never
88+
;(layout[name] as any) = value
8389
}
8490

8591
const getColorVal = function (name: keyof Layout): string {
@@ -91,7 +97,11 @@ export const useConfig = defineStore(
9197
}
9298
}
9399

94-
return { layout, lang, menuWidth, setLang, setLayoutMode, setLayout, getColorVal, onSetLayoutColor }
100+
const setCrud = (name: keyof Crud, value: any) => {
101+
;(crud[name] as any) = value
102+
}
103+
104+
return { layout, lang, crud, menuWidth, setLang, setLayoutMode, setLayout, getColorVal, onSetLayoutColor, setCrud }
95105
},
96106
{
97107
persist: {

web/src/stores/interface/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ export interface Lang {
6060
langArray: { name: string; value: string }[]
6161
}
6262

63+
export interface Crud {
64+
// 日志同步方式
65+
syncType: 'manual' | 'automatic'
66+
// 已同步记录被更新时,是否自动重新同步
67+
syncedUpdate: 'no' | 'yes'
68+
// 自动同步时是否分享至开源社区
69+
syncAutoPublic: 'no' | 'yes'
70+
}
71+
6372
export interface NavTabs {
6473
// 激活 tab 的 index
6574
activeIndex: number

0 commit comments

Comments
 (0)