Skip to content

Commit 94e30b3

Browse files
Merge pull request #5 from eevanlai-stack/eevanlai-stack-patch-2
Update app.py
2 parents dbe3686 + f16ea8a commit 94e30b3

File tree

1 file changed

+278
-0
lines changed

1 file changed

+278
-0
lines changed

app.py

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,284 @@ def handle_bad_request(err):
185185
@app.route('/healthz')
186186
def healthz():
187187
return jsonify({'status': 'ok'})
188+
from flask import Flask, request, jsonify
189+
from werkzeug.exceptions import BadRequest
190+
from flask_cors import CORS
191+
192+
app = Flask(__name__)
193+
CORS(app)
194+
195+
196+
# In-memory data store for employees (for demo purposes)
197+
employees = {
198+
'E001': {
199+
'id': 'E001',
200+
'name': 'John Doe',
201+
'email': '[email protected]',
202+
'phone': '123-456-7890',
203+
'title': 'Software Engineer',
204+
'department': 'Engineering',
205+
'salary': 5000,
206+
'status': 'active',
207+
},
208+
'E002': {
209+
'id': 'E002',
210+
'name': 'Jane Smith',
211+
'email': '[email protected]',
212+
'phone': '987-654-3210',
213+
'title': 'Product Manager',
214+
'department': 'Product',
215+
'salary': 6500,
216+
'status': 'active',
217+
},
218+
}
219+
220+
221+
# 1. GPS定位
222+
@app.route('/gps', methods=['GET'])
223+
def get_location():
224+
# 这里需要调用GPS定位的API,获取用户的经纬度信息
225+
# 由于GPS定位需要在移动设备上才能实现,这里我们只返回一个模拟数据
226+
location = {'latitude': 31.2304, 'longitude': 121.4737}
227+
return jsonify(location)
228+
229+
230+
# 2. EPF (Employee Provident Fund) 公积金计算
231+
@app.route('/epf', methods=['POST'])
232+
def calculate_epf():
233+
data = request.get_json(silent=True) or {}
234+
if 'salary' not in data:
235+
raise BadRequest('Missing field: salary')
236+
try:
237+
salary = float(data.get('salary'))
238+
except (TypeError, ValueError):
239+
raise BadRequest('Invalid salary')
240+
241+
# EPF的计算逻辑,这里假设员工和雇主各缴纳11%和13%
242+
employee_contribution = round(salary * 0.11, 2)
243+
employer_contribution = round(salary * 0.13, 2)
244+
total_contribution = round(employee_contribution + employer_contribution, 2)
245+
return jsonify({
246+
'employee_contribution': employee_contribution,
247+
'employer_contribution': employer_contribution,
248+
'total_contribution': total_contribution
249+
})
250+
251+
252+
# 3. PERKESO (Social Security Organization) 社险计算
253+
@app.route('/perkeso', methods=['POST'])
254+
def calculate_perkeso():
255+
data = request.get_json(silent=True) or {}
256+
if 'salary' not in data:
257+
raise BadRequest('Missing field: salary')
258+
try:
259+
salary = float(data.get('salary'))
260+
except (TypeError, ValueError):
261+
raise BadRequest('Invalid salary')
262+
263+
# PERKESO的计算逻辑,具体费率需要参考官方数据
264+
employee_contribution = round(salary * 0.005, 2)
265+
employer_contribution = round(salary * 0.01, 2)
266+
total_contribution = round(employee_contribution + employer_contribution, 2)
267+
return jsonify({
268+
'employee_contribution': employee_contribution,
269+
'employer_contribution': employer_contribution,
270+
'total_contribution': total_contribution
271+
})
272+
273+
274+
# 4. PCB (Potongan Cukai Bulanan) 月度所得税计算
275+
@app.route('/pcb', methods=['POST'])
276+
def calculate_pcb():
277+
data = request.get_json(silent=True) or {}
278+
if 'salary' not in data:
279+
raise BadRequest('Missing field: salary')
280+
try:
281+
salary = float(data.get('salary'))
282+
except (TypeError, ValueError):
283+
raise BadRequest('Invalid salary')
284+
285+
# PCB的计算逻辑非常复杂,需要参考LHDN的官方指南
286+
# 这里我们只返回一个模拟数据
287+
pcb = round(salary * 0.1, 2)
288+
return jsonify({'pcb': pcb})
289+
290+
291+
# 5. 打卡功能
292+
@app.route('/clock_in', methods=['POST'])
293+
def clock_in():
294+
data = request.get_json(silent=True) or {}
295+
employee_id = data.get('employee_id')
296+
if not employee_id:
297+
raise BadRequest('Missing field: employee_id')
298+
# 这里需要记录打卡的时间和地点
299+
return jsonify({'message': 'Clock in successful'})
300+
301+
302+
# 6. 考勤表
303+
@app.route('/attendance', methods=['GET'])
304+
def get_attendance():
305+
employee_id = request.args.get('employee_id')
306+
if not employee_id:
307+
raise BadRequest('Missing query param: employee_id')
308+
# 这里需要从数据库中查询考勤记录
309+
attendance_records = [
310+
{'date': '2023-11-01', 'clock_in': '09:00', 'clock_out': '18:00'},
311+
{'date': '2023-11-02', 'clock_in': '09:05', 'clock_out': '17:55'}
312+
]
313+
return jsonify(attendance_records)
314+
315+
316+
# 7. 个人Payroll,加入Advance
317+
@app.route('/payroll', methods=['GET'])
318+
def get_payroll():
319+
employee_id = request.args.get('employee_id')
320+
if not employee_id:
321+
raise BadRequest('Missing query param: employee_id')
322+
# 这里需要从数据库中查询Payroll记录
323+
payroll_data = {
324+
'salary': 5000,
325+
'epf': 550,
326+
'perkeso': 50,
327+
'pcb': 500,
328+
'advance': 200,
329+
'net_salary': 4600
330+
}
331+
return jsonify(payroll_data)
332+
333+
334+
# 8. Advance 预支工资
335+
@app.route('/advance', methods=['POST'])
336+
def request_advance():
337+
data = request.get_json(silent=True) or {}
338+
employee_id = data.get('employee_id')
339+
amount = data.get('amount')
340+
if not employee_id:
341+
raise BadRequest('Missing field: employee_id')
342+
try:
343+
amount = float(amount)
344+
except (TypeError, ValueError):
345+
raise BadRequest('Invalid amount')
346+
# 这里需要记录预支工资的请求
347+
return jsonify({'message': 'Advance request submitted'})
348+
349+
350+
# 9. 个人资料
351+
@app.route('/profile', methods=['GET'])
352+
def get_profile():
353+
employee_id = request.args.get('employee_id')
354+
if not employee_id:
355+
raise BadRequest('Missing query param: employee_id')
356+
# 这里需要从数据库中查询个人资料
357+
profile_data = {
358+
'name': 'John Doe',
359+
'email': '[email protected]',
360+
'phone': '123-456-7890'
361+
}
362+
return jsonify(profile_data)
363+
364+
365+
# 9.1 员工管理(Employee Management)
366+
@app.route('/employees', methods=['GET'])
367+
def list_employees():
368+
# 返回所有员工列表
369+
return jsonify(list(employees.values()))
370+
371+
372+
@app.route('/employees/<employee_id>', methods=['GET'])
373+
def get_employee(employee_id):
374+
emp = employees.get(employee_id)
375+
if not emp:
376+
return jsonify({'error': f'Employee {employee_id} not found'}), 404
377+
return jsonify(emp)
378+
379+
380+
@app.route('/employees', methods=['POST'])
381+
def create_employee():
382+
data = request.get_json(silent=True) or {}
383+
employee_id = data.get('id') or data.get('employee_id')
384+
if not employee_id:
385+
raise BadRequest('Missing field: id')
386+
if employee_id in employees:
387+
return jsonify({'error': f'Employee {employee_id} already exists'}), 409
388+
389+
# 基础字段
390+
new_emp = {
391+
'id': employee_id,
392+
'name': data.get('name', ''),
393+
'email': data.get('email', ''),
394+
'phone': data.get('phone', ''),
395+
'title': data.get('title', ''),
396+
'department': data.get('department', ''),
397+
'salary': data.get('salary', 0),
398+
'status': data.get('status', 'active'),
399+
}
400+
employees[employee_id] = new_emp
401+
return jsonify(new_emp), 201
402+
403+
404+
@app.route('/employees/<employee_id>', methods=['PUT'])
405+
def update_employee(employee_id):
406+
emp = employees.get(employee_id)
407+
if not emp:
408+
return jsonify({'error': f'Employee {employee_id} not found'}), 404
409+
data = request.get_json(silent=True) or {}
410+
# 更新允许的字段
411+
for key in ['name', 'email', 'phone', 'title', 'department', 'salary', 'status']:
412+
if key in data:
413+
emp[key] = data[key]
414+
employees[employee_id] = emp
415+
return jsonify(emp)
416+
417+
418+
@app.route('/employees/<employee_id>', methods=['DELETE'])
419+
def delete_employee(employee_id):
420+
if employee_id not in employees:
421+
return jsonify({'error': f'Employee {employee_id} not found'}), 404
422+
deleted = employees.pop(employee_id)
423+
return jsonify({'message': 'Deleted', 'employee': deleted})
424+
425+
426+
# 10. 聊天功能
427+
@app.route('/chat', methods=['POST'])
428+
def send_message():
429+
data = request.get_json(silent=True) or {}
430+
sender_id = data.get('sender_id')
431+
receiver_id = data.get('receiver_id')
432+
message = data.get('message')
433+
if not sender_id or not receiver_id or not message:
434+
raise BadRequest('Missing sender_id, receiver_id or message')
435+
# 这里需要将消息保存到数据库中,并通知接收方
436+
return jsonify({'message': 'Message sent'})
437+
438+
439+
# 11. 语言翻译
440+
@app.route('/translate', methods=['POST'])
441+
def translate_text():
442+
data = request.get_json(silent=True) or {}
443+
text = data.get('text')
444+
target_language = data.get('target_language')
445+
if not text or not target_language:
446+
raise BadRequest('Missing text or target_language')
447+
# 这里需要调用翻译API,将文本翻译成目标语言
448+
# 这里我们只返回一个模拟数据
449+
translated_text = f'Translated to {target_language}: {text}'
450+
return jsonify({'translated_text': translated_text})
451+
452+
453+
@app.errorhandler(BadRequest)
454+
def handle_bad_request(err):
455+
return jsonify({'error': str(err)}), 400
456+
457+
458+
@app.route('/healthz')
459+
def healthz():
460+
return jsonify({'status': 'ok'})
461+
462+
463+
if __name__ == '__main__':
464+
# For local development; in production, use gunicorn with wsgi:app
465+
app.run(host='0.0.0.0', port=8000, debug=True)
188466

189467

190468
if __name__ == '__main__':

0 commit comments

Comments
 (0)