chanjs 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/config.js CHANGED
@@ -41,7 +41,7 @@ const baseConfig = {
41
41
  password: "123456",
42
42
  database: "chancms",
43
43
  charset: "utf8mb4",
44
- }
44
+ },
45
45
  };
46
46
 
47
47
  // 导出配置对象
package/core/helper.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import knex from 'knex';
2
+ import merge from 'deepmerge';
2
3
 
3
4
  /**
4
5
  * @description 实例化一个类,并将该类的所有方法绑定到一个新的对象上。
@@ -97,4 +98,8 @@ export const zodValidator = (schemas) => (req, res, next) => {
97
98
  req[key] = result.data;
98
99
  }
99
100
  next();
100
- };
101
+ };
102
+
103
+
104
+ // 重新导出 deepmerge 的命名导出
105
+ export { default as merge } from 'deepmerge';
@@ -23,5 +23,34 @@ export default class Controller {
23
23
  return result;
24
24
  }
25
25
 
26
+ success(data) {
27
+ return {
28
+ success: true,
29
+ msg: '操作成功',
30
+ code: 200,
31
+ data
32
+ };
33
+ }
34
+
35
+ fail(data, code = 201) {
36
+ return {
37
+ success: false,
38
+ msg: '操作失败',
39
+ code,
40
+ data
41
+ };
42
+ }
43
+
44
+
45
+ err(data={}, code = 500){
46
+ return {
47
+ success: false,
48
+ msg: '系统异常',
49
+ code,
50
+ data
51
+ };
52
+ }
53
+
54
+
26
55
 
27
56
  }
@@ -1,3 +1,24 @@
1
+ const errCode = {
2
+ "ECONNREFUSED": "数据库连接被拒绝,请检查数据库服务是否正常运行。",
3
+ "ER_ACCESS_DENIED_ERROR": "无权限访问,账号或密码错误。",
4
+ "ER_ROW_IS_REFERENCED_2": "无法删除或更新记录,存在关联数据。",
5
+ "ER_BAD_FIELD_ERROR": "SQL语句中包含无效字段,请检查查询条件或列名。",
6
+ "ER_DUP_ENTRY": "插入失败:数据重复,违反唯一性约束。",
7
+ "ER_NO_SUCH_TABLE": "操作失败:目标表不存在。",
8
+ "ETIMEOUT": "数据库操作超时,请稍后再试。"
9
+ }
10
+ const getDefaultErrorMessage = (error) => {
11
+ if (error.message.includes('syntax') ||
12
+ error.message.includes('SQL')) {
13
+ return '数据库语法错误,请检查您的查询语句。';
14
+ } else if (error.message.includes('Connection closed')) {
15
+ return '数据库连接已关闭,请重试。';
16
+ } else if (error.message.includes('permission')) {
17
+ return '数据库权限不足,请检查配置。';
18
+ }
19
+ return '数据库发生未知错误,请稍后重试。';
20
+ }
21
+
1
22
  class BaseService {
2
23
  /**
3
24
  * @description 构造函数
@@ -10,15 +31,21 @@ class BaseService {
10
31
  }
11
32
 
12
33
  /**
13
- * @description 查询表所有记录,慎用
14
- * @param {Object} query - 包含查询参数的对象
15
- * @returns {Promise} 返回所有记录
16
- */
17
- all(query = {}) {
18
- if (Object.keys(query).length === 0) {
19
- return this.DB(this.model).select();
34
+ * @description 查询表所有记录,慎用
35
+ * @param {Object} query - 包含查询参数的对象
36
+ * @returns {Promise} 返回所有记录
37
+ */
38
+ async all(query = {}) {
39
+ try {
40
+ let dbQuery = this.DB(this.model);
41
+ if (Object.keys(query).length > 0) {
42
+ dbQuery = dbQuery.where(query);
43
+ }
44
+ let res = await dbQuery.select();
45
+ return this.success(res);
46
+ } catch (err) {
47
+ return this.error(err);
20
48
  }
21
- return this.DB(this.model).where(query).select();
22
49
  }
23
50
 
24
51
  /**
@@ -31,22 +58,22 @@ class BaseService {
31
58
  * @returns {Promise} 返回匹配条件的记录或记录列表
32
59
  */
33
60
  async findById({ query, field = [], len = 1 }) {
34
- let dataQuery = this.DB(this.model).where(query);
35
-
36
- // 字段筛选
37
- if (field.length > 0) {
38
- dataQuery = dataQuery.select(field);
39
- }
40
-
41
- // 根据len决定是获取单条记录还是多条记录
42
- if (len === 1) {
43
- dataQuery = dataQuery.first();
44
- } else if (len > 1) {
45
- dataQuery = dataQuery.limit(len);
61
+ try {
62
+ let dataQuery = this.DB(this.model).where(query);
63
+ if (field.length > 0) {
64
+ dataQuery = dataQuery.select(field);
65
+ }
66
+ if (len === 1) {
67
+ dataQuery = dataQuery.first();
68
+ } else if (len > 1) {
69
+ dataQuery = dataQuery.limit(len);
70
+ }
71
+ let res = await dataQuery;
72
+ console.log('111',res);
73
+ return this.success(res || (len === 1 ? {} : []));
74
+ } catch (err) {
75
+ return this.error(err);
46
76
  }
47
- let res = await dataQuery;
48
- //返回结果 undefined 则返回空数组或空对象
49
- return res || (len === 1 ? {} : []);
50
77
  }
51
78
 
52
79
 
@@ -56,11 +83,15 @@ class BaseService {
56
83
  * @returns {Promise<boolean>} 返回操作是否成功
57
84
  */
58
85
  async insert(data = {}) {
59
- if (Object.keys(data).length === 0) {
60
- return false;
86
+ try {
87
+ if (Object.keys(data).length === 0) {
88
+ return this.fail('插入数据不能为空');
89
+ }
90
+ const result = await this.DB(this.model).insert(data);
91
+ return this.success(result?.length > 0 || !!result)
92
+ } catch (err) {
93
+ return this.error(err); // 假设你有 this.error() 的封装
61
94
  }
62
- const result = await this.DB(this.model).insert(data);
63
- return result?.length > 0 || !!result;
64
95
  }
65
96
 
66
97
  /**
@@ -69,17 +100,15 @@ class BaseService {
69
100
  * @returns {Promise<Array|Number>} 返回插入后的记录或受影响行数,具体取决于数据库驱动
70
101
  */
71
102
  async insertMany(records = []) {
72
- // 如果没有提供数据或者数据为空,则直接返回 false 或者抛出异常
73
- if (records.length === 0) {
74
- console.log('插入数据不能为空')
75
- return false;
103
+ try {
104
+ if (records.length === 0) {
105
+ return this.fail('插入数据不能为空');
106
+ }
107
+ const result = await this.DB(this.model).insert(records);
108
+ return this.success(result)
109
+ } catch (err) {
110
+ return this.error(err); // 假设你有 this.error() 的封装
76
111
  }
77
-
78
- // 执行插入操作并获取结果
79
- const result = await this.DB(this.model).insert(records);
80
-
81
- // 返回插入的结果
82
- return result;
83
112
  }
84
113
 
85
114
  /**
@@ -88,63 +117,63 @@ class BaseService {
88
117
  * @returns {Promise<boolean>} 返回操作是否成功(即是否有任何记录被删除)
89
118
  */
90
119
  async delete(query = {}) {
91
- if (Object.keys(query).length === 0) {
92
- return false;
120
+ try {
121
+ if (Object.keys(query).length === 0) {
122
+ return this.error("请指定删除条件");
123
+ }
124
+ const affectedRows = await this.DB(this.model).where(query).del();
125
+ return this.success(affectedRows > 0);
126
+ } catch (err) {
127
+ return this.error(err); // 假设你有 this.error() 的封装
93
128
  }
94
- const affectedRows = await this.DB(this.model).where(query).del();
95
- return affectedRows > 0;
96
129
  }
97
130
  /**
98
131
  * @description 根据指定条件更新记录
99
132
  * @param {Object} query - 查询条件
100
- * @param {number} params - 保存内容
101
- * @returns {Promise<boolean>} 返回操作是否成功
133
+ * @param {Object} params - 要更新的数据
134
+ * @returns {Promise<boolean>} 返回操作是否成功(是否有行被更新)
102
135
  */
103
136
  async update({ query, params } = {}) {
104
- const result = await this.DB(this.model).where(query).update(params);
105
- return { affectedRows: result };
137
+ try {
138
+ console.log('update--->',query, params)
139
+ if (!query || !params || Object.keys(query).length === 0) {
140
+ return this.fail("参数错误");
141
+ }
142
+ const result = await this.DB(this.model).where(query).update(params);
143
+ return this.success(!!result);
144
+ } catch (err) {
145
+ return this.error(err); // 假设你有 this.error() 的封装
146
+ }
106
147
  }
107
148
 
108
-
109
149
  /**
110
150
  * @description 批量更新多条记录(基于事务保证原子性)
111
- * @param {Array<{query: Object, params: Object}>} updates - 更新操作数组,每个元素包含查询条件和更新内容
112
- * @returns {Promise<{ affectedRows: number[] }>} 返回每个操作影响的行数数组
151
+ * @param {Array<{query: Object, params: Object}>} updates - 更新操作数组
152
+ * @returns {Promise<boolean>} 返回是否所有记录都更新成功
113
153
  */
114
154
  async updateMany(updates = []) {
115
- // 参数合法性校验
116
155
  if (!Array.isArray(updates)) {
117
- throw new Error('参数必须为数组格式');
156
+ return this.fail('参数必须为数组格式');
118
157
  }
119
-
120
158
  // 获取事务对象
121
159
  const trx = await this.DB.transaction();
122
-
123
160
  try {
124
- const affectedRows = [];
125
- // 循环处理每个更新操作
126
161
  for (const { query, params } of updates) {
127
- // 执行单个更新操作,使用事务对象替换原有knex实例
128
- const result = await trx(this.model)
129
- .where(query)
130
- .update(params);
131
- affectedRows.push(result);
162
+ const result = await trx(this.model).where(query).update(params);
163
+ if (result === 0) {
164
+ await trx.rollback(); // 有一条失败就回滚
165
+ return this.fail('更新失败');
166
+ }
132
167
  }
133
- // 提交事务
168
+
134
169
  await trx.commit();
135
- // 返回影响行数数组(与入参顺序一致)
136
- return { affectedRows };
170
+ return this.success(true);
137
171
  } catch (err) {
138
- // 回滚事务
139
172
  await trx.rollback();
140
- // 错误向上抛出,由调用者处理
141
- throw err;
173
+ return this.error(error);
142
174
  }
143
175
  }
144
176
 
145
-
146
-
147
-
148
177
  /**
149
178
  * 查找所有符合条件的记录,并提供分页信息。
150
179
  * @param {Object} options - 包含查询参数的对象
@@ -155,28 +184,29 @@ class BaseService {
155
184
  * @returns {Promise<Object>} 返回包含数据列表、总记录数、当前页、每页大小的对象
156
185
  */
157
186
  async query({ current = 1, pageSize = 10, query = {}, field = [] }) {
158
- const offset = (current - 1) * pageSize;
159
- let countQuery = this.DB(this.model).count("* as total");
160
- let dataQuery = this.DB(this.model);
161
- // 应用查询条件
162
- if (Object.keys(query).length > 0) {
163
- Object.entries(query).forEach(([key, value]) => {
164
- dataQuery = dataQuery.where(key, value);
165
- countQuery = countQuery.where(key, value);
166
- })
167
- }
168
-
169
- //字段筛选
170
- if (field.length > 0) {
171
- dataQuery = dataQuery.select(field);
172
- }
173
-
174
- //并行执行获取总记录数和分页数据的查询
175
- const [totalResult, list] = await Promise.all([countQuery.first(), dataQuery.offset(offset).limit(pageSize)]);
176
- // 提取总记录数
177
- const total = totalResult?.total || 0;
187
+ try {
188
+ const offset = (current - 1) * pageSize;
189
+ let countQuery = this.DB(this.model).count("* as total");
190
+ let dataQuery = this.DB(this.model);
191
+ // 应用查询条件
192
+ if (Object.keys(query).length > 0) {
193
+ Object.entries(query).forEach(([key, value]) => {
194
+ dataQuery = dataQuery.where(key, value);
195
+ countQuery = countQuery.where(key, value);
196
+ })
197
+ }
178
198
 
179
- return { list, total, current, pageSize };
199
+ //字段筛选
200
+ if (field.length > 0) {
201
+ dataQuery = dataQuery.select(field);
202
+ }
203
+ //并行执行获取总记录数和分页数据的查询
204
+ const [totalResult, list] = await Promise.all([countQuery.first(), dataQuery.offset(offset).limit(pageSize)]);
205
+ // 提取总记录数
206
+ const total = totalResult?.total || 0;
207
+ return this.success({ list, total, current, pageSize });
208
+ } catch (err) { }
209
+ return this.error(err);
180
210
  }
181
211
 
182
212
 
@@ -186,24 +216,54 @@ class BaseService {
186
216
  * @returns {Promise<number>} 返回符合条件的记录数量
187
217
  */
188
218
  async count(query = []) {
189
- let dataQuery = this.DB(this.model);
190
- if (query.length > 0) {
191
- query.forEach((condition) => {
192
- dataQuery = dataQuery.where(condition);
193
- });
219
+ try {
220
+ let dataQuery = this.DB(this.model);
221
+ if (query.length > 0) {
222
+ query.forEach((condition) => {
223
+ dataQuery = dataQuery.where(condition);
224
+ });
225
+ }
226
+ const result = await dataQuery.count("* as total").first();
227
+ return this.success(result?.total || 0);
228
+ } catch (error) {
229
+ return this.error(error);
194
230
  }
195
- const result = await dataQuery.count("* as total").first();
196
- return result.total || 0;
197
231
  }
198
232
 
233
+
199
234
  error(err) {
200
- console.error(err);
235
+ console.error('-->',err);
236
+ // 从映射表中查找对应的错误信息
237
+ const message = errCode[err.code] || getDefaultErrorMessage(err);
201
238
  return {
202
- code: 500,
203
- msg: "数据库操作失败",
204
- data: { sql: err.sql, sqlMessage: err.sqlMessage },
239
+ success: false,
240
+ msg: message,
241
+ code: 500, // 或者根据错误类型区分
242
+ data: {
243
+ sql: err.sql,
244
+ sqlMessage: err.sqlMessage
245
+ }
205
246
  };
206
247
  }
207
248
 
249
+ fail(msg = "操作失败", data = {}) {
250
+ console.error(msg);
251
+ return {
252
+ success: false,
253
+ msg,
254
+ code: 201, // 或者根据错误类型区分
255
+ data: data
256
+ }
257
+ }
258
+
259
+ success(data = {}, msg = "操作成功") {
260
+ return {
261
+ success: true,
262
+ msg,
263
+ code: 200,
264
+ data
265
+ }
266
+ }
267
+
208
268
  }
209
269
  export default BaseService;
package/index.js CHANGED
@@ -19,7 +19,7 @@ class Chan {
19
19
  static modules = {};
20
20
  static plugins = {};
21
21
  static config = config;
22
- static Controller = Controller;
22
+ static Controller = Controller;
23
23
  static Service = Service;
24
24
  static Cache = Cache;
25
25
  static Task = Task;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "chanjs",
4
- "version": "1.2.3",
4
+ "version": "1.2.5",
5
5
  "description": "chanjs基于express5 纯js研发的轻量级mvc框架。",
6
6
  "main": "index.js",
7
7
  "module": "index.js",
@@ -29,6 +29,7 @@
29
29
  "knex": "^3.1.0",
30
30
  "morgan": "^1.10.0",
31
31
  "mysql2": "^3.14.1",
32
- "schedule": "^0.5.0"
32
+ "schedule": "^0.5.0",
33
+ "deepmerge": "^4.3.1"
33
34
  }
34
35
  }