routes.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. from flask import Blueprint, jsonify, request, current_app, send_from_directory
  2. from app import db
  3. from app.models import User, Carousel, StrategicCooperation, Partner, CaseCategory, CooperationCase, News, DevelopmentHistory, Honor, CompanyInfo
  4. from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
  5. from werkzeug.utils import secure_filename
  6. import os
  7. import uuid
  8. bp = Blueprint('api', __name__, url_prefix='/api')
  9. static_bp = Blueprint('static_files', __name__)
  10. # Helper for image upload
  11. ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
  12. def allowed_file(filename):
  13. return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
  14. @bp.route('/upload', methods=['POST'])
  15. @jwt_required()
  16. def upload_file():
  17. if 'file' not in request.files:
  18. return jsonify({'error': 'No file part'}), 400
  19. file = request.files['file']
  20. if file.filename == '':
  21. return jsonify({'error': 'No selected file'}), 400
  22. if file and allowed_file(file.filename):
  23. filename = secure_filename(file.filename)
  24. # Unique filename
  25. unique_filename = f"{uuid.uuid4().hex}_{filename}"
  26. upload_path = current_app.config['UPLOAD_FOLDER']
  27. if not os.path.exists(upload_path):
  28. os.makedirs(upload_path)
  29. file.save(os.path.join(upload_path, unique_filename))
  30. return jsonify({'url': f'/static/uploads/{unique_filename}'}), 201
  31. return jsonify({'error': 'File type not allowed'}), 400
  32. # Serve static files
  33. @static_bp.route('/static/uploads/<filename>')
  34. def uploaded_file(filename):
  35. return send_from_directory(current_app.config['UPLOAD_FOLDER'], filename)
  36. # Auth
  37. @bp.route('/login', methods=['POST'])
  38. def login():
  39. data = request.get_json()
  40. username = data.get('username')
  41. password = data.get('password')
  42. user = User.query.filter_by(username=username).first()
  43. if user and user.check_password(password):
  44. access_token = create_access_token(identity=username)
  45. return jsonify(access_token=access_token, username=username), 200
  46. return jsonify({"msg": "Bad username or password"}), 401
  47. # User Management
  48. @bp.route('/users', methods=['GET'])
  49. @jwt_required()
  50. def get_users():
  51. users = User.query.all()
  52. return jsonify([{'id': u.id, 'username': u.username, 'created_at': u.created_at} for u in users])
  53. @bp.route('/users', methods=['POST'])
  54. @jwt_required()
  55. def create_user():
  56. data = request.get_json()
  57. if User.query.filter_by(username=data['username']).first():
  58. return jsonify({'error': 'User already exists'}), 400
  59. user = User(username=data['username'])
  60. user.set_password(data['password'])
  61. db.session.add(user)
  62. db.session.commit()
  63. return jsonify({'message': 'User created'}), 201
  64. @bp.route('/users/<int:id>', methods=['PUT'])
  65. @jwt_required()
  66. def update_user(id):
  67. user = User.query.get_or_404(id)
  68. data = request.get_json()
  69. if 'password' in data and data['password']:
  70. user.set_password(data['password'])
  71. db.session.commit()
  72. return jsonify({'message': 'User updated'})
  73. @bp.route('/users/<int:id>', methods=['DELETE'])
  74. @jwt_required()
  75. def delete_user(id):
  76. user = User.query.get_or_404(id)
  77. if user.username == 'admin':
  78. return jsonify({'error': 'Cannot delete admin'}), 403
  79. db.session.delete(user)
  80. db.session.commit()
  81. return jsonify({'message': 'User deleted'})
  82. # Strategic Cooperation
  83. @bp.route('/strategic-cooperation', methods=['GET'])
  84. def get_strategic_cooperation():
  85. items = StrategicCooperation.query.all()
  86. return jsonify([{'id': i.id, 'name': i.name, 'description': i.description, 'image_url': i.image_url, 'link': i.link} for i in items])
  87. @bp.route('/strategic-cooperation', methods=['POST'])
  88. @jwt_required()
  89. def create_strategic_cooperation():
  90. data = request.get_json()
  91. item = StrategicCooperation(name=data['name'], description=data.get('description'), image_url=data.get('image_url'), link=data.get('link'))
  92. db.session.add(item)
  93. db.session.commit()
  94. return jsonify({'message': 'Created', 'id': item.id}), 201
  95. @bp.route('/strategic-cooperation/<int:id>', methods=['PUT'])
  96. @jwt_required()
  97. def update_strategic_cooperation(id):
  98. item = StrategicCooperation.query.get_or_404(id)
  99. data = request.get_json()
  100. item.name = data.get('name', item.name)
  101. item.description = data.get('description', item.description)
  102. item.image_url = data.get('image_url', item.image_url)
  103. item.link = data.get('link', item.link)
  104. db.session.commit()
  105. return jsonify({'message': 'Updated'})
  106. @bp.route('/strategic-cooperation/<int:id>', methods=['DELETE'])
  107. @jwt_required()
  108. def delete_strategic_cooperation(id):
  109. item = StrategicCooperation.query.get_or_404(id)
  110. db.session.delete(item)
  111. db.session.commit()
  112. return jsonify({'message': 'Deleted'})
  113. # Partners
  114. @bp.route('/partners', methods=['GET'])
  115. def get_partners():
  116. items = Partner.query.all()
  117. return jsonify([{'id': i.id, 'name': i.name, 'image_url': i.image_url, 'link': i.link} for i in items])
  118. @bp.route('/partners', methods=['POST'])
  119. @jwt_required()
  120. def create_partner():
  121. data = request.get_json()
  122. item = Partner(name=data['name'], image_url=data.get('image_url'), link=data.get('link'))
  123. db.session.add(item)
  124. db.session.commit()
  125. return jsonify({'message': 'Created', 'id': item.id}), 201
  126. @bp.route('/partners/<int:id>', methods=['PUT'])
  127. @jwt_required()
  128. def update_partner(id):
  129. item = Partner.query.get_or_404(id)
  130. data = request.get_json()
  131. item.name = data.get('name', item.name)
  132. item.image_url = data.get('image_url', item.image_url)
  133. item.link = data.get('link', item.link)
  134. db.session.commit()
  135. return jsonify({'message': 'Updated'})
  136. @bp.route('/partners/<int:id>', methods=['DELETE'])
  137. @jwt_required()
  138. def delete_partner(id):
  139. item = Partner.query.get_or_404(id)
  140. db.session.delete(item)
  141. db.session.commit()
  142. return jsonify({'message': 'Deleted'})
  143. # Carousel
  144. @bp.route('/carousels', methods=['GET'])
  145. def get_carousels():
  146. location = request.args.get('location')
  147. query = Carousel.query
  148. if location:
  149. query = query.filter_by(location=location)
  150. items = query.order_by(Carousel.sort_order).all()
  151. return jsonify([{'id': i.id, 'image_url': i.image_url, 'link': i.link, 'location': i.location, 'sort_order': i.sort_order} for i in items])
  152. @bp.route('/carousels', methods=['POST'])
  153. @jwt_required()
  154. def create_carousel():
  155. data = request.get_json()
  156. item = Carousel(
  157. image_url=data['image_url'],
  158. link=data.get('link'),
  159. location=data['location'],
  160. sort_order=data.get('sort_order', 0)
  161. )
  162. db.session.add(item)
  163. db.session.commit()
  164. return jsonify({'message': 'Created', 'id': item.id}), 201
  165. @bp.route('/carousels/<int:id>', methods=['PUT'])
  166. @jwt_required()
  167. def update_carousel(id):
  168. item = Carousel.query.get_or_404(id)
  169. data = request.get_json()
  170. item.image_url = data.get('image_url', item.image_url)
  171. item.link = data.get('link', item.link)
  172. item.location = data.get('location', item.location)
  173. item.sort_order = data.get('sort_order', item.sort_order)
  174. db.session.commit()
  175. return jsonify({'message': 'Updated'})
  176. @bp.route('/carousels/<int:id>', methods=['DELETE'])
  177. @jwt_required()
  178. def delete_carousel(id):
  179. item = Carousel.query.get_or_404(id)
  180. db.session.delete(item)
  181. db.session.commit()
  182. return jsonify({'message': 'Deleted'})
  183. # Case Categories
  184. @bp.route('/case-categories', methods=['GET'])
  185. def get_case_categories():
  186. section = request.args.get('section')
  187. query = CaseCategory.query
  188. if section:
  189. query = query.filter_by(section=section)
  190. items = query.all()
  191. return jsonify([{'id': i.id, 'name': i.name, 'section': i.section} for i in items])
  192. @bp.route('/case-categories', methods=['POST'])
  193. @jwt_required()
  194. def create_case_category():
  195. data = request.get_json()
  196. item = CaseCategory(name=data['name'], section=data['section'])
  197. db.session.add(item)
  198. db.session.commit()
  199. return jsonify({'message': 'Created', 'id': item.id}), 201
  200. @bp.route('/case-categories/<int:id>', methods=['PUT'])
  201. @jwt_required()
  202. def update_case_category(id):
  203. item = CaseCategory.query.get_or_404(id)
  204. data = request.get_json()
  205. item.name = data.get('name', item.name)
  206. item.section = data.get('section', item.section)
  207. db.session.commit()
  208. return jsonify({'message': 'Updated'})
  209. @bp.route('/case-categories/<int:id>', methods=['DELETE'])
  210. @jwt_required()
  211. def delete_case_category(id):
  212. item = CaseCategory.query.get_or_404(id)
  213. db.session.delete(item)
  214. db.session.commit()
  215. return jsonify({'message': 'Deleted'})
  216. # Cooperation Cases
  217. @bp.route('/cases', methods=['GET'])
  218. def get_cases():
  219. section = request.args.get('section')
  220. category_id = request.args.get('category_id')
  221. query = CooperationCase.query
  222. if section:
  223. query = query.filter_by(section=section)
  224. if category_id:
  225. query = query.filter_by(category_id=category_id)
  226. items = query.all()
  227. return jsonify([{
  228. 'id': i.id,
  229. 'title': i.title,
  230. 'image_url': i.image_url,
  231. 'description': i.description,
  232. 'section': i.section,
  233. 'category_id': i.category_id,
  234. 'category_name': i.category.name if i.category else None
  235. } for i in items])
  236. @bp.route('/cases', methods=['POST'])
  237. @jwt_required()
  238. def create_case():
  239. data = request.get_json()
  240. item = CooperationCase(
  241. title=data['title'],
  242. image_url=data.get('image_url'),
  243. description=data.get('description'),
  244. section=data['section'],
  245. category_id=data.get('category_id')
  246. )
  247. db.session.add(item)
  248. db.session.commit()
  249. return jsonify({'message': 'Created', 'id': item.id}), 201
  250. @bp.route('/cases/<int:id>', methods=['PUT'])
  251. @jwt_required()
  252. def update_case(id):
  253. item = CooperationCase.query.get_or_404(id)
  254. data = request.get_json()
  255. item.title = data.get('title', item.title)
  256. item.image_url = data.get('image_url', item.image_url)
  257. item.description = data.get('description', item.description)
  258. item.section = data.get('section', item.section)
  259. item.category_id = data.get('category_id', item.category_id)
  260. db.session.commit()
  261. return jsonify({'message': 'Updated'})
  262. @bp.route('/cases/<int:id>', methods=['DELETE'])
  263. @jwt_required()
  264. def delete_case(id):
  265. item = CooperationCase.query.get_or_404(id)
  266. db.session.delete(item)
  267. db.session.commit()
  268. return jsonify({'message': 'Deleted'})
  269. # News
  270. @bp.route('/news', methods=['GET'])
  271. def get_news():
  272. items = News.query.order_by(News.publish_time.desc()).all()
  273. return jsonify([{
  274. 'id': i.id,
  275. 'title': i.title,
  276. 'image_url': i.image_url,
  277. 'author': i.author,
  278. 'publish_time': i.publish_time,
  279. 'created_at': i.created_at
  280. } for i in items])
  281. @bp.route('/news/<int:id>', methods=['GET'])
  282. def get_news_detail(id):
  283. item = News.query.get_or_404(id)
  284. return jsonify({
  285. 'id': item.id,
  286. 'title': item.title,
  287. 'content': item.content,
  288. 'image_url': item.image_url,
  289. 'author': item.author,
  290. 'publish_time': item.publish_time,
  291. 'created_at': item.created_at
  292. })
  293. @bp.route('/news', methods=['POST'])
  294. @jwt_required()
  295. def create_news():
  296. data = request.get_json()
  297. item = News(
  298. title=data['title'],
  299. content=data.get('content'),
  300. image_url=data.get('image_url'),
  301. author=data.get('author')
  302. )
  303. db.session.add(item)
  304. db.session.commit()
  305. return jsonify({'message': 'Created', 'id': item.id}), 201
  306. @bp.route('/news/<int:id>', methods=['PUT'])
  307. @jwt_required()
  308. def update_news(id):
  309. item = News.query.get_or_404(id)
  310. data = request.get_json()
  311. item.title = data.get('title', item.title)
  312. item.content = data.get('content', item.content)
  313. item.image_url = data.get('image_url', item.image_url)
  314. item.author = data.get('author', item.author)
  315. db.session.commit()
  316. return jsonify({'message': 'Updated'})
  317. @bp.route('/news/<int:id>', methods=['DELETE'])
  318. @jwt_required()
  319. def delete_news(id):
  320. item = News.query.get_or_404(id)
  321. db.session.delete(item)
  322. db.session.commit()
  323. return jsonify({'message': 'Deleted'})
  324. # Development History
  325. @bp.route('/development-history', methods=['GET'])
  326. def get_development_history():
  327. items = DevelopmentHistory.query.order_by(DevelopmentHistory.year.desc()).all()
  328. return jsonify([{'id': i.id, 'year': i.year, 'title': i.title, 'description': i.description} for i in items])
  329. @bp.route('/development-history', methods=['POST'])
  330. @jwt_required()
  331. def create_development_history():
  332. data = request.get_json()
  333. item = DevelopmentHistory(
  334. year=data['year'],
  335. title=data['title'],
  336. description=data.get('description')
  337. )
  338. db.session.add(item)
  339. db.session.commit()
  340. return jsonify({'message': 'Created', 'id': item.id}), 201
  341. @bp.route('/development-history/<int:id>', methods=['PUT'])
  342. @jwt_required()
  343. def update_development_history(id):
  344. item = DevelopmentHistory.query.get_or_404(id)
  345. data = request.get_json()
  346. item.year = data.get('year', item.year)
  347. item.title = data.get('title', item.title)
  348. item.description = data.get('description', item.description)
  349. db.session.commit()
  350. return jsonify({'message': 'Updated'})
  351. @bp.route('/development-history/<int:id>', methods=['DELETE'])
  352. @jwt_required()
  353. def delete_development_history(id):
  354. item = DevelopmentHistory.query.get_or_404(id)
  355. db.session.delete(item)
  356. db.session.commit()
  357. return jsonify({'message': 'Deleted'})
  358. # Honors
  359. @bp.route('/honors', methods=['GET'])
  360. def get_honors():
  361. items = Honor.query.all()
  362. return jsonify([{'id': i.id, 'title': i.title, 'image_url': i.image_url} for i in items])
  363. @bp.route('/honors', methods=['POST'])
  364. @jwt_required()
  365. def create_honor():
  366. data = request.get_json()
  367. item = Honor(
  368. title=data['title'],
  369. image_url=data.get('image_url')
  370. )
  371. db.session.add(item)
  372. db.session.commit()
  373. return jsonify({'message': 'Created', 'id': item.id}), 201
  374. @bp.route('/honors/<int:id>', methods=['PUT'])
  375. @jwt_required()
  376. def update_honor(id):
  377. item = Honor.query.get_or_404(id)
  378. data = request.get_json()
  379. item.title = data.get('title', item.title)
  380. item.image_url = data.get('image_url', item.image_url)
  381. db.session.commit()
  382. return jsonify({'message': 'Updated'})
  383. @bp.route('/honors/<int:id>', methods=['DELETE'])
  384. @jwt_required()
  385. def delete_honor(id):
  386. item = Honor.query.get_or_404(id)
  387. db.session.delete(item)
  388. db.session.commit()
  389. return jsonify({'message': 'Deleted'})
  390. # Company Info
  391. @bp.route('/company-info', methods=['GET'])
  392. def get_company_info():
  393. info = CompanyInfo.query.first()
  394. if not info:
  395. return jsonify({})
  396. return jsonify({
  397. 'id': info.id,
  398. 'intro_content': info.intro_content,
  399. 'intro_image_url': info.intro_image_url,
  400. 'vision': info.vision,
  401. 'mission': info.mission,
  402. 'values': info.values,
  403. 'phone': info.phone,
  404. 'email': info.email,
  405. 'qrcode_url': info.qrcode_url
  406. })
  407. @bp.route('/company-info', methods=['POST', 'PUT'])
  408. @jwt_required()
  409. def update_company_info():
  410. info = CompanyInfo.query.first()
  411. data = request.get_json()
  412. if not info:
  413. info = CompanyInfo()
  414. db.session.add(info)
  415. info.intro_content = data.get('intro_content', info.intro_content)
  416. info.intro_image_url = data.get('intro_image_url', info.intro_image_url)
  417. info.vision = data.get('vision', info.vision)
  418. info.mission = data.get('mission', info.mission)
  419. info.values = data.get('values', info.values)
  420. info.phone = data.get('phone', info.phone)
  421. info.email = data.get('email', info.email)
  422. info.qrcode_url = data.get('qrcode_url', info.qrcode_url)
  423. db.session.commit()
  424. return jsonify({'message': 'Updated'})