正在显示
27 个修改的文件
包含
2172 行增加
和
0 行删除
taxbot/.gitignore
0 → 100644
taxbot/README.md
0 → 100644
taxbot/TaxBot.py
0 → 100644
1 | +import sys | ||
2 | +import socket | ||
3 | +from common.utils import * | ||
4 | +from PyQt5.QtWidgets import QApplication | ||
5 | +from forms import mainform | ||
6 | +from forms import loginform | ||
7 | +from forms import floderfrom | ||
8 | +from common.config import * | ||
9 | +from common.log import BotLogger | ||
10 | + | ||
11 | +logger = BotLogger(os.path.basename(__file__), logname=1).getLogger() | ||
12 | +BOT_STATUS = False | ||
13 | +HOST = '127.0.0.1' | ||
14 | +PORT = 55555 | ||
15 | + | ||
16 | + | ||
17 | +if __name__ == '__main__': | ||
18 | + filename = sys.argv[0] | ||
19 | + if not load_config(): | ||
20 | + logger.error("加载配置文件失败!") | ||
21 | + sys.exit() | ||
22 | + | ||
23 | + db_path = os.path.join(os.getcwd(), get_cfg().db_path) | ||
24 | + if not os.path.exists(db_path): | ||
25 | + if not DBClass().init_db(): | ||
26 | + logger.error("初始化数据库文件失败!") | ||
27 | + sys.exit(1) | ||
28 | + | ||
29 | + tenant_id = get_cfg().tenant_id | ||
30 | + tenant_type = get_cfg().tenant_type | ||
31 | + | ||
32 | + if tenant_id == "" or tenant_id is None: | ||
33 | + logger.error("获取配置文件tenant_id数据异常") | ||
34 | + sys.exit(2) | ||
35 | + if tenant_type not in ['0', '1']: | ||
36 | + logger.error("获取配置文件tenant_type数据异常") | ||
37 | + sys.exit(3) | ||
38 | + | ||
39 | + crease_shoutcut() # 创建快捷方式到自启动文件夹中 | ||
40 | + | ||
41 | + app = QApplication(sys.argv) | ||
42 | + | ||
43 | + login_form = loginform.Ui_LoginWindow() | ||
44 | + login_form.setupUi() | ||
45 | + | ||
46 | + main_form = mainform.Ui_MainWindow() | ||
47 | + main_form.setupUi() | ||
48 | + | ||
49 | + floder_form = floderfrom.Ui_FloderWindow(main_form) | ||
50 | + floder_form.setupUi() | ||
51 | + | ||
52 | + is_err = False, '' | ||
53 | + result = login_check(tenant_id, tenant_type) | ||
54 | + if result == 0: | ||
55 | + login_form.LoginWindow.show() | ||
56 | + login_form.pushButton_2.clicked.connect(lambda: login_form.login(floder_form, tenant_id, tenant_type)) | ||
57 | + elif result == 1: | ||
58 | + floder_form.FloderWindow.show() | ||
59 | + elif result == 2: | ||
60 | + main_form.mainform_show() | ||
61 | + elif result == -1: | ||
62 | + is_err = True, '连接数据库失败!' | ||
63 | + elif result == -2: | ||
64 | + is_err = True, '网络连接异常,请稍后重试!' | ||
65 | + | ||
66 | + if not is_err[0]: | ||
67 | + do_task_thread = mainform.UpdateDoTask() | ||
68 | + do_task_thread.update_date.connect(main_form.update_dotask) # 更新待办理账户管理线程 | ||
69 | + do_task_thread.start() | ||
70 | + | ||
71 | + doed_task_thread = mainform.UpdateDoedTask() | ||
72 | + doed_task_thread.update_date.connect(main_form.update_doedtask) # 更新已办理账户管理线程 | ||
73 | + doed_task_thread.start() | ||
74 | + | ||
75 | + main_form.commandLinkButton_2.clicked.connect(lambda: main_form.login_off(filename)) | ||
76 | + main_form.commandLinkButton_3.clicked.connect(lambda: main_form.get_do_task()) | ||
77 | + main_form.commandLinkButton_4.clicked.connect(lambda: main_form.get_doed_task()) | ||
78 | + main_form.commandLinkButton_5.clicked.connect(lambda: main_form.start_task(tenant_id, tenant_type)) | ||
79 | + else: | ||
80 | + logger.info("socket对象关闭") | ||
81 | + open_msg(is_err[1]) | ||
82 | + | ||
83 | + sys.exit(app.exec_()) |
taxbot/common/__init__.py
0 → 100644
taxbot/common/api.py
0 → 100644
1 | +import requests | ||
2 | +import time | ||
3 | +import oss2 | ||
4 | +from common.log import * | ||
5 | + | ||
6 | +logger = BotLogger(os.path.basename(__file__), logname=1).getLogger() | ||
7 | + | ||
8 | + | ||
9 | +def handle_error(res, normal_status_code): | ||
10 | + """ | ||
11 | + 统一处理workai平台返回的error | ||
12 | + :param res: 调用接口的返回 | ||
13 | + :param normal_status_code: 正常返回的status code | ||
14 | + :return: 返回错误信息 | ||
15 | + """ | ||
16 | + if res is None or res.status_code == normal_status_code: | ||
17 | + return '' | ||
18 | + | ||
19 | + logger.info('The res is %s' % res) | ||
20 | + err = '网络或服务器繁忙!' | ||
21 | + try: | ||
22 | + if 'message' in res.json(): | ||
23 | + err = res.json()['message'] | ||
24 | + except Exception as e: | ||
25 | + logger.error(str(e)) | ||
26 | + | ||
27 | + return err | ||
28 | + | ||
29 | + | ||
30 | +def get_token_by_password(username, password, tenant_id, tenant_type): | ||
31 | + """ | ||
32 | + 密码方式获取access_token | ||
33 | + :param username: 系统管理员用户 | ||
34 | + :param password: 系统管理员密码 | ||
35 | + :param tenant_id: 客户在workai云平台唯一表示 | ||
36 | + :return: 返回access_token, refresh_token 以及error, access_token用于访问接口的令牌, refresh_token | ||
37 | + 用于刷新获取新的access_token, error为返回的错误信息 | ||
38 | + """ | ||
39 | + data = { | ||
40 | + 'grant_type': 'password', | ||
41 | + 'username': username, | ||
42 | + 'password': password, | ||
43 | + 'scope': 'global_access:tenant_admin,tenant:%s,tenant_type:%s' % (tenant_id, tenant_type), | ||
44 | + } | ||
45 | + | ||
46 | + path = '%s/uaa/v1/auth/tokens' % WACLOUD_API_ENDPOINT | ||
47 | + try: | ||
48 | + res = requests.post(path, json=data, timeout=10) | ||
49 | + err = handle_error(res, 200) | ||
50 | + if err != '': | ||
51 | + logger.error('Could not get the token by password for user: %s, tenant: %s' % (username, tenant_id)) | ||
52 | + return '', '', err, None | ||
53 | + | ||
54 | + ret = res.json() | ||
55 | + company, username, play_type = '', '', '' | ||
56 | + if tenant_type == '0': | ||
57 | + play_type = 'HRO' | ||
58 | + elif tenant_type == '1': | ||
59 | + play_type = 'HR' | ||
60 | + | ||
61 | + try: | ||
62 | + company = ret['tenant']['name'] | ||
63 | + username = ret['user']['name'] | ||
64 | + except Exception as e: | ||
65 | + logger.error(str(e)) | ||
66 | + | ||
67 | + return ret['access_token'], ret['refresh_token'], '', (company, username, play_type) | ||
68 | + except Exception as e: | ||
69 | + logger.error(str(e)) | ||
70 | + return '', '', '网络或服务器异常,请稍后再试!', None | ||
71 | + | ||
72 | + | ||
73 | +def refresh_token(rtoken, tenant_id): | ||
74 | + """ | ||
75 | + 刷新token方式获取access_token | ||
76 | + :return: 返回access_token, refresh_token 以及error, access_token用于访问接口的令牌, refresh_token | ||
77 | + 用于刷新获取新的access_token, error为返回的错误信息 | ||
78 | + """ | ||
79 | + data = { | ||
80 | + 'grant_type': 'refresh_token', | ||
81 | + 'refresh_token': rtoken, | ||
82 | + 'scope': 'global_access:tenant_admin,tenant:%s' % tenant_id, | ||
83 | + } | ||
84 | + | ||
85 | + path = '%s/uaa/v1/auth/tokens' % WACLOUD_API_ENDPOINT | ||
86 | + res = requests.post(path, json=data) | ||
87 | + | ||
88 | + err = handle_error(res, 200) | ||
89 | + if err != '': | ||
90 | + logger.error('Could not get the token by refresh token for tenant: %s' % (tenant_id,)) | ||
91 | + return '', '', err | ||
92 | + | ||
93 | + ret = res.json() | ||
94 | + return ret['access_token'], ret['refresh_token'], '' | ||
95 | + | ||
96 | + | ||
97 | +def upload_file(ctx, local_path, tenant_type, file_name): | ||
98 | + """上传附件""" | ||
99 | + object_path = "" | ||
100 | + if ctx is None or local_path is None: | ||
101 | + return 401, object_path | ||
102 | + | ||
103 | + headers = {'Authorization': 'Bearer %s' % ctx['access_token']} | ||
104 | + path = '%s/filemeta/v2/inits' % (WACLOUD_API_ENDPOINT,) | ||
105 | + if tenant_type == "0": | ||
106 | + data = {"object_type": "hro", "access_type": "sdk"} | ||
107 | + elif tenant_type == "1": | ||
108 | + data = {"object_type": "hr", "access_type": "sdk"} | ||
109 | + else: | ||
110 | + return 401, '配置文件设置tenant_type的值有误' | ||
111 | + | ||
112 | + res = None | ||
113 | + try: | ||
114 | + res = requests.post(path, json=data, headers=headers, timeout=120) | ||
115 | + if res.status_code == 401: | ||
116 | + access_token, _refresh_token, err = refresh_token(ctx['refresh_token'], ctx['tenant_id']) | ||
117 | + if err != '': | ||
118 | + return 401, object_path | ||
119 | + ctx['access_token'] = access_token | ||
120 | + ctx['refresh_token'] = _refresh_token | ||
121 | + headers = {'Authorization': 'Bearer %s' % ctx['access_token']} | ||
122 | + res = requests.post(path, json=data, headers=headers, timeout=120) | ||
123 | + | ||
124 | + err = handle_error(res, 200) | ||
125 | + if err != '': | ||
126 | + return res.status_code, object_path | ||
127 | + except Exception as e: | ||
128 | + logger.error(str(e)) | ||
129 | + return 401, str(e) | ||
130 | + | ||
131 | + try: | ||
132 | + datas = res.json() | ||
133 | + # 使用临时token中的认证信息初始化StsAuth实例。 | ||
134 | + # auth = oss2.Auth(datas['access_key_id'], datas['access_key_secret']) | ||
135 | + auth = oss2.StsAuth(datas['access_key_id'], datas['access_key_secret'], datas['security_token']) | ||
136 | + # 使用StsAuth实例初始化存储空间。 | ||
137 | + bucket = oss2.Bucket(auth, datas['domain'], datas['bucket']) | ||
138 | + object_path = datas['object_path'] + "/" + file_name | ||
139 | + result = bucket.put_object_from_file(object_path, local_path) | ||
140 | + return result.status, object_path | ||
141 | + except Exception as e: | ||
142 | + logger.error(str(e)) | ||
143 | + return 403, str(e) | ||
144 | + | ||
145 | + | ||
146 | +def update_object_path(ctx, tenant_type, object_path, types, file_name): | ||
147 | + """上传文件路径到saas平台""" | ||
148 | + if tenant_type == "0" or tenant_type == "1": | ||
149 | + path = '%s/payroll/v1/do-import-data?type=%s' % (WACLOUD_API_ENDPOINT, types) | ||
150 | + else: | ||
151 | + return False, '平台类型设置有误' | ||
152 | + | ||
153 | + headers = {'Authorization': 'Bearer %s' % ctx['access_token']} | ||
154 | + bucket = '/hro/' | ||
155 | + if 'hx' in WACLOUD_API_ENDPOINT: | ||
156 | + bucket = '/hxhro/' | ||
157 | + elif "xsb" in WACLOUD_API_ENDPOINT: | ||
158 | + bucket = "/xsbhro/" | ||
159 | + elif "engma" in WACLOUD_API_ENDPOINT: | ||
160 | + bucket = "/engmahro/" | ||
161 | + elif "anbo" in WACLOUD_API_ENDPOINT: | ||
162 | + bucket = "/anbohro/" | ||
163 | + elif "teda" in WACLOUD_API_ENDPOINT: | ||
164 | + bucket = "/tedahro/" | ||
165 | + elif "hwapi" in WACLOUD_API_ENDPOINT: | ||
166 | + bucket = "/hro/" | ||
167 | + elif "jincao" in WACLOUD_API_ENDPOINT: | ||
168 | + bucket = "/jchro/" | ||
169 | + elif 'jincao' in WACLOUD_API_ENDPOINT: | ||
170 | + bucket = '/jchro/' | ||
171 | + elif 'bhgn' in WACLOUD_API_ENDPOINT: | ||
172 | + bucket = '/bhgnhro/' | ||
173 | + elif 'gongyuanhr' in WACLOUD_API_ENDPOINT: | ||
174 | + bucket = '/szgyhro/' | ||
175 | + | ||
176 | + | ||
177 | + object_path = bucket + object_path | ||
178 | + data = { | ||
179 | + "object_path": object_path, | ||
180 | + "file_name": file_name | ||
181 | + } | ||
182 | + | ||
183 | + try: | ||
184 | + res = requests.post(path, json=data, headers=headers, timeout=120) | ||
185 | + if res.status_code == 401: | ||
186 | + time.sleep(2) | ||
187 | + res = requests.post(path, json=data, headers=headers, timeout=120) | ||
188 | + | ||
189 | + err = handle_error(res, 200) | ||
190 | + if err != '': | ||
191 | + logger.error("上传失败:{file}, 原因:{reason}".format(file=object_path, reason=err)) | ||
192 | + if 'Internal Server Error' in err: | ||
193 | + err = '数据助手sheet附表内容错误' | ||
194 | + return False, err | ||
195 | + return True, '任务办理成功' | ||
196 | + except Exception as e: | ||
197 | + logger.error(str(e)) | ||
198 | + return False, '请求服务器异常:{}'.format(str(e)) |
taxbot/common/config.py
0 → 100644
1 | +from configparser import * | ||
2 | +import os | ||
3 | +from common.log import * | ||
4 | + | ||
5 | +logger = BotLogger(os.path.basename(__file__)).getLogger() | ||
6 | + | ||
7 | + | ||
8 | +class Config(object): | ||
9 | + """ | ||
10 | + controller配置项 | ||
11 | + """ | ||
12 | + def __init__(self, config_path=''): | ||
13 | + self.config_path = config_path | ||
14 | + if self.config_path != '': | ||
15 | + self.__parse() | ||
16 | + | ||
17 | + def __parse(self): | ||
18 | + config_parser = ConfigParser() | ||
19 | + config_parser.read(self.config_path) | ||
20 | + | ||
21 | + self.db_path = 'taxbot.db' | ||
22 | + self.server_name = '数据智能助手.exe' | ||
23 | + | ||
24 | + try: | ||
25 | + self.db_path = config_parser.get('data', 'path') | ||
26 | + self.server_name = config_parser.get('data', 'server_name') | ||
27 | + except (NoSectionError, NoOptionError) as e: | ||
28 | + logger.debug('The config file does not include the data path: ' + str(e)) | ||
29 | + | ||
30 | + self.tenant_id = '' | ||
31 | + self.tenant_type = '0' | ||
32 | + try: | ||
33 | + self.tenant_id = config_parser.get('hro', 'tenant_id') | ||
34 | + self.tenant_type = config_parser.get('hro', 'tenant_type') | ||
35 | + except (NoSectionError, NoOptionError) as e: | ||
36 | + logger.error(str(e)) | ||
37 | + logger.info('db tenant_id is {tenant_id}'.format(tenant_id=self.tenant_id)) | ||
38 | + logger.info('db tenant_type is {tenant_type}'.format(tenant_type=self.tenant_type)) | ||
39 | + | ||
40 | + # self.ac_floder = '' | ||
41 | + # try: | ||
42 | + # self.ac_floder = config_parser.get('ac_floder', 'path') | ||
43 | + # except (NoSectionError, NoOptionError) as e: | ||
44 | + # logger.error(str(e)) | ||
45 | + | ||
46 | + | ||
47 | + self.delay = 600 | ||
48 | + self.mid_delay = 7200 | ||
49 | + try: | ||
50 | + self.delay = config_parser.get('delay_time', 'delay') | ||
51 | + self.mid_delay = config_parser.get('delay_time', 'mid_delay') | ||
52 | + except (NoSectionError, NoOptionError) as e: | ||
53 | + logger.error(str(e)) | ||
54 | + # logger.info('delay is: {delay}, mid_delay is: {mid_delay}'.format(delay=self.delay, mid_delay=self.mid_delay)) | ||
55 | + | ||
56 | + | ||
57 | +cfg = Config() | ||
58 | + | ||
59 | + | ||
60 | +def configure(config_path): | ||
61 | + global cfg | ||
62 | + cfg = Config(config_path) | ||
63 | + return cfg | ||
64 | + | ||
65 | + | ||
66 | +def get_cfg(): | ||
67 | + return cfg |
taxbot/common/constant.py
0 → 100644
1 | + | ||
2 | +# WACLOUD_API_ENDPOINT = "https://api.workai.com.cn" | ||
3 | +# WACLOUD_API_ENDPOINT = "https://xsb.cnthr.com/bizapi" | ||
4 | +# WACLOUD_API_ENDPOINT = "http://api.engma.net" | ||
5 | +WACLOUD_API_ENDPOINT = "https://api.fjhxrl.com" | ||
6 | +# WACLOUD_API_ENDPOINT = "https://api.anbohro.com" | ||
7 | +# WACLOUD_API_ENDPOINT = "https://pay.tedahr.com/bizapi" | ||
8 | +# WACLOUD_API_ENDPOINT = "https://api.jincaohr.com" | ||
9 | +# WACLOUD_API_ENDPOINT = "https://api.jincaohr.com" | ||
10 | +# WACLOUD_API_ENDPOINT = "https://hwapi.workai.com.cn" | ||
11 | +# WACLOUD_API_ENDPOINT = "http://api.bhgnhr.com" | ||
12 | +# WACLOUD_API_ENDPOINT = "http://47.110.158.110:20000" | ||
13 | +# WACLOUD_API_ENDPOINT = "https://api.ghyc.com.cn" | ||
14 | +# WACLOUD_API_ENDPOINT = "https://api.gongyuanhr.com" | ||
15 | + | ||
16 | + | ||
17 | +# log name begin | ||
18 | +LOG_COMMON_NAME = 'common.log' # 0 | ||
19 | +LOG_SERVER_NAME = 'server.log' # 1 | ||
20 | +LOG_LOGIN_NAME = 'login.log' # 2 | ||
21 | +LOG_FLODER_NAME = 'floder.log' # 3 | ||
22 | +# log name end | ||
23 | + | ||
24 | +# status begin | ||
25 | +DB_STATUS_FAIL = 'fail' | ||
26 | +# status end | ||
27 | + | ||
28 | +STATUS_AVAIL = 'avail' | ||
29 | +STATUS_RUNNING = 'running' | ||
30 | +STATUS_FAIL = 'fail' | ||
31 | +STATUS_SUCCESS = 'success' | ||
32 | + | ||
33 | +# type begin | ||
34 | +TASK_TYPE_INSURANCE = "insurance" | ||
35 | +TASK_TYPE_SALARY = "salary" | ||
36 | +# type end | ||
37 | + | ||
38 | +# 根据上面的api 修改 | ||
39 | +# VERSION = 'bhgnhr-V2.5' | ||
40 | +# VERSION = 'gongyuanhr-V2.5' | ||
41 | +# VERSION = 'workai-V2.5' | ||
42 | +VERSION = 'fjhxrl-V2.5' | ||
43 | + | ||
44 | + | ||
45 | +# 修改配置 | ||
46 | +# taxbot.conf 中[hro] tenant_id | ||
47 | + | ||
48 | +# 福建海峡人力资源股份有限公司 302972189366300672 |
taxbot/common/dbutils.py
0 → 100644
1 | +import os | ||
2 | +import sqlite3 | ||
3 | +from common.constant import * | ||
4 | +from common.config import * | ||
5 | +from common.log import BotLogger | ||
6 | + | ||
7 | +logger = BotLogger(os.path.basename(__file__), logname=1).getLogger() | ||
8 | + | ||
9 | + | ||
10 | +class DBClass(object): | ||
11 | + """数据库操作类""" | ||
12 | + def __init__(self): | ||
13 | + self.db_path = get_cfg().db_path | ||
14 | + self.conn = None | ||
15 | + self.cur = None | ||
16 | + | ||
17 | + def get_conn(self): | ||
18 | + """获取数据库操作对象""" | ||
19 | + self.conn = sqlite3.connect(self.db_path) | ||
20 | + if self.conn is None: | ||
21 | + self.conn = sqlite3.connect(':memory:') | ||
22 | + | ||
23 | + self.cur = self.conn.cursor() | ||
24 | + | ||
25 | + def close_all(self): | ||
26 | + """关闭数据库操作对象""" | ||
27 | + if self.cur is not None: | ||
28 | + self.cur.close() | ||
29 | + | ||
30 | + if self.conn is not None: | ||
31 | + self.conn.close() | ||
32 | + | ||
33 | + def init_db(self): | ||
34 | + account_table_sql = ''' | ||
35 | + CREATE TABLE IF NOT EXISTS account ( | ||
36 | + ac_account VARCHAR(30) UNIQUE , | ||
37 | + ac_passwd VARCHAR(50) NOT NULL, | ||
38 | + ac_floder VARCHAR(300), | ||
39 | + company VARCHAR(100), | ||
40 | + username VARCHAR(20), | ||
41 | + plat_type VARCHAR(10) | ||
42 | + ) | ||
43 | + ''' | ||
44 | + | ||
45 | + task_table_sql = ''' | ||
46 | + CREATE TABLE IF NOT EXISTS task ( | ||
47 | + task_id VARCHAR(20) PRIMARY KEY, | ||
48 | + filename VARCHAR(100) NOT NULL, | ||
49 | + bus_type VARCHAR(10) NOT NULL, | ||
50 | + plat_type VARCHAR(10) NOT NULL, | ||
51 | + task_time VARCHAR(30) NOT NULL, | ||
52 | + status VARCHAR(20), | ||
53 | + comment VARCHAR(100) | ||
54 | + ) | ||
55 | + ''' | ||
56 | + | ||
57 | + self.get_conn() | ||
58 | + if self.conn is None or self.cur is None: | ||
59 | + logger.error('初始化数据库失败') | ||
60 | + return False | ||
61 | + else: | ||
62 | + self.cur.execute(account_table_sql) | ||
63 | + self.cur.execute(task_table_sql) | ||
64 | + logger.info('初始化数据库成功') | ||
65 | + self.conn.commit() | ||
66 | + self.close_all() | ||
67 | + return True | ||
68 | + | ||
69 | + def execute(self, sql, args=tuple()): | ||
70 | + try: | ||
71 | + self.get_conn() | ||
72 | + if self.conn is None or self.cur is None: | ||
73 | + logger.error('获取数据库操作对象失败') | ||
74 | + return False | ||
75 | + else: | ||
76 | + try: | ||
77 | + self.cur.execute(sql, args) | ||
78 | + result = self.cur.fetchall() | ||
79 | + self.conn.commit() | ||
80 | + self.close_all() | ||
81 | + return result | ||
82 | + except Exception as e: | ||
83 | + logger.error(str(e)) | ||
84 | + return DB_STATUS_FAIL | ||
85 | + except Exception as e: | ||
86 | + logger.error(str(e)) |
taxbot/common/log.py
0 → 100644
1 | +import logging | ||
2 | +import sys | ||
3 | +import os | ||
4 | +from common.constant import * | ||
5 | + | ||
6 | + | ||
7 | +class BotLogger(object): | ||
8 | + def __init__(self, filename, logname=0, out=1): | ||
9 | + """ | ||
10 | + 获取日志处理对象 | ||
11 | + :param appName: 应用程序名 | ||
12 | + :param logFileName: 日志文件名 | ||
13 | + :param out: 设置输出端:0:默认控制台,1:输入文件,其他:控制台和文件都输出 | ||
14 | + :return: 返回日志对象 | ||
15 | + """ | ||
16 | + self.appName = filename.split('.')[0] | ||
17 | + self.logFileName = os.getcwd() + "\\log\\" | ||
18 | + if not os.path.exists(self.logFileName): | ||
19 | + os.makedirs(self.logFileName) | ||
20 | + if logname == 1: | ||
21 | + self.logFileName += LOG_SERVER_NAME | ||
22 | + elif logname == 2: | ||
23 | + self.logFileName += LOG_LOGIN_NAME | ||
24 | + elif logname == 3: | ||
25 | + self.logFileName += LOG_FLODER_NAME | ||
26 | + elif logname == 0: | ||
27 | + self.logFileName += LOG_COMMON_NAME | ||
28 | + self.out = out | ||
29 | + | ||
30 | + def getLogger(self): | ||
31 | + # 获取logging实例 | ||
32 | + logger = logging.getLogger(self.appName) | ||
33 | + # 指定输出的格式 | ||
34 | + formatter = logging.Formatter('%(name)s %(lineno)d %(asctime)s %(levelname)-8s:%(message)s') | ||
35 | + | ||
36 | + # 文件日志 | ||
37 | + file_handler = logging.FileHandler(self.logFileName, encoding='utf-8') | ||
38 | + file_handler.setFormatter(formatter) | ||
39 | + | ||
40 | + # 控制台日志 | ||
41 | + console_handler = logging.StreamHandler(sys.stdout) | ||
42 | + console_handler.setFormatter(formatter) | ||
43 | + | ||
44 | + # # 指定日志的最低输出级别 | ||
45 | + logger.setLevel(logging.INFO) # 20 | ||
46 | + | ||
47 | + # 为logger添加具体的日志处理器输出端 | ||
48 | + if self.out == 1: | ||
49 | + logger.addHandler(file_handler) | ||
50 | + elif self.out == 0: | ||
51 | + logger.addHandler(console_handler) | ||
52 | + else: | ||
53 | + logger.addHandler(file_handler) | ||
54 | + logger.addHandler(console_handler) | ||
55 | + return logger | ||
56 | + | ||
57 | + | ||
58 | + | ||
59 | + |
taxbot/common/utils.py
0 → 100644
1 | +import hashlib, requests, platform | ||
2 | +import uuid, os, time, sys | ||
3 | +import shutil, datetime | ||
4 | +import win32com.client | ||
5 | +from optparse import OptionParser | ||
6 | +from common import config | ||
7 | +from forms import msgform | ||
8 | +from common.api import * | ||
9 | +from common.log import BotLogger | ||
10 | +from common.dbutils import * | ||
11 | +from threading import Thread | ||
12 | +from queue import Queue | ||
13 | +import win32api, win32con | ||
14 | +from os import path | ||
15 | +import winshell | ||
16 | +import socket | ||
17 | + | ||
18 | +logger = BotLogger(os.path.basename(__file__), logname=1).getLogger() | ||
19 | +q = Queue() | ||
20 | + | ||
21 | + | ||
22 | +def open_msg(msg=''): | ||
23 | + """打开自定义消息提示框""" | ||
24 | + msg_form = msgform.Ui_MsgWindow() | ||
25 | + msg_form.setupUi(msg) | ||
26 | + msg_form.MsgWindow.show() | ||
27 | + | ||
28 | + Thread(target=auto_form, args=(msg_form,), daemon=True).start() | ||
29 | + | ||
30 | + | ||
31 | +def auto_form(form): | ||
32 | + time.sleep(5) | ||
33 | + if form.MsgWindow.isVisible(): | ||
34 | + form.MsgWindow.close() | ||
35 | + | ||
36 | + | ||
37 | +def check_net_isactive(): | ||
38 | + """检查当前机器网络是否可用""" | ||
39 | + url = 'https://hro.workai.com.cn/' | ||
40 | + for i in range(3): | ||
41 | + try: | ||
42 | + res = requests.get(url) | ||
43 | + if res.status_code == 200: | ||
44 | + return True | ||
45 | + except Exception as e: | ||
46 | + logger.error("网络不可用:" + str(e)) | ||
47 | + time.sleep(1) | ||
48 | + | ||
49 | + return False | ||
50 | + | ||
51 | + | ||
52 | +def hash_md5(attrs): | ||
53 | + md5 = hashlib.md5() | ||
54 | + md5.update(''.join(attrs).encode('utf-8')) | ||
55 | + return md5.hexdigest() | ||
56 | + | ||
57 | + | ||
58 | +def hash_file(file_path): | ||
59 | + try: | ||
60 | + f = open(file_path) | ||
61 | + except IOError: | ||
62 | + return None | ||
63 | + digest = hashlib.sha512() | ||
64 | + while True: | ||
65 | + chunk = f.read(2048) | ||
66 | + if not chunk: | ||
67 | + break | ||
68 | + digest.update(chunk.encode('utf-8')) | ||
69 | + f.close() | ||
70 | + return digest.hexdigest() | ||
71 | + | ||
72 | + | ||
73 | +def get_datetime(): | ||
74 | + """返回固定格式的日期、时间格式""" | ||
75 | + now = datetime.datetime.now() | ||
76 | + now = now.strftime("%Y-%m-%d %H:%M:%S") | ||
77 | + return now | ||
78 | + | ||
79 | + | ||
80 | +def get_timestamp(): | ||
81 | + """返回毫秒级时间戳""" | ||
82 | + t = time.time() | ||
83 | + now_stamp = int(round(t * 1000)) | ||
84 | + return now_stamp | ||
85 | + | ||
86 | + | ||
87 | +def check_procname_exist(procname): | ||
88 | + """检查进程名是否存在""" | ||
89 | + try: | ||
90 | + wmi = win32com.client.GetObject('winmgmts:') | ||
91 | + proc_code_cov = wmi.ExecQuery("select * from Win32_Process where Name='%s'" % procname) | ||
92 | + if len(proc_code_cov) > 0: | ||
93 | + logger.info('Check ProName: {} Exist'.format(procname)) | ||
94 | + return True | ||
95 | + return False | ||
96 | + except Exception as e: | ||
97 | + logger.error(str(e)) | ||
98 | + return False | ||
99 | + | ||
100 | + | ||
101 | +def kill_procname(procname): | ||
102 | + """杀掉已经启动的进程""" | ||
103 | + if check_procname_exist(procname): | ||
104 | + os.system('taskkill /F /IM ' + procname) | ||
105 | + | ||
106 | + | ||
107 | +def load_config(): | ||
108 | + """加载配置文件""" | ||
109 | + try: | ||
110 | + parser = OptionParser(prog='salary', usage="%prog [options]") | ||
111 | + | ||
112 | + parser.add_option("-c", "--config_path", action="store", type="string", dest="config_path", help="配置文件路径") | ||
113 | + (options, args) = parser.parse_args() | ||
114 | + | ||
115 | + config_path = options.config_path | ||
116 | + if not config_path: | ||
117 | + config_path = os.getcwd() + '/taxbot.conf' | ||
118 | + if not os.path.exists(config_path): | ||
119 | + logger.error('The config file %s does not exist' % config_path) | ||
120 | + return False | ||
121 | + if not os.path.isfile(config_path): | ||
122 | + logger.error('The config path %s is not a file' % config_path) | ||
123 | + return False | ||
124 | + | ||
125 | + try: | ||
126 | + config.configure(config_path) | ||
127 | + except Exception as e: | ||
128 | + logger.error(str(e)) | ||
129 | + return False | ||
130 | + return True | ||
131 | + except Exception as e: | ||
132 | + logger.error(str(e)) | ||
133 | + return False | ||
134 | + | ||
135 | + | ||
136 | +def login_check(tenant_id, tenant_type): | ||
137 | + global q | ||
138 | + Thread(target=__start_login_check, args=(tenant_id, tenant_type, q)).start() | ||
139 | + result = q.get() | ||
140 | + return result | ||
141 | + | ||
142 | + | ||
143 | +def __start_login_check(tenant_id, tenant_type, q): | ||
144 | + result = DBClass().execute('SELECT * FROM account') | ||
145 | + if result == DB_STATUS_FAIL: | ||
146 | + q.put(-1) | ||
147 | + elif not result: | ||
148 | + q.put(0) | ||
149 | + else: | ||
150 | + if check_net_isactive(): | ||
151 | + # 调用登录接口,检查用户名密码的有效性 | ||
152 | + access_token, refresh_token, err, t_info = get_token_by_password(result[0][0], result[0][1], tenant_id, tenant_type) | ||
153 | + if err != '': | ||
154 | + logger.error("获取授权信息失败: " + err) | ||
155 | + DBClass().execute("DELETE FROM account") | ||
156 | + q.put(0) | ||
157 | + else: | ||
158 | + # 检工作目录文件夹是否存在 | ||
159 | + floder = result[0][2] | ||
160 | + if floder or floder != '': | ||
161 | + if not os.path.exists(floder): | ||
162 | + logger.error("当前设置的目录不存在:" + floder) | ||
163 | + q.put(1) | ||
164 | + else: | ||
165 | + q.put(2) | ||
166 | + else: | ||
167 | + q.put(1) | ||
168 | + else: | ||
169 | + q.put(-2) | ||
170 | + | ||
171 | + | ||
172 | +def order_task(file_list): | ||
173 | + """排序列表中的文件名,社保优先、工资最后""" | ||
174 | + ins_file_list, salary_file_list = [], [] | ||
175 | + for item in file_list: | ||
176 | + if '社保' in item[1]: | ||
177 | + ins_file_list.append(item) | ||
178 | + elif '工资' in item[1]: | ||
179 | + salary_file_list.append(item) | ||
180 | + return ins_file_list, salary_file_list | ||
181 | + | ||
182 | + | ||
183 | +def check_is_file(work_path, files): | ||
184 | + """检查是否是所需要的文件""" | ||
185 | + sure_lst, err_lst = [], [] | ||
186 | + if not files: | ||
187 | + return sure_lst | ||
188 | + for file in files: | ||
189 | + file_path = work_path + '/' + file | ||
190 | + if os.path.isfile(file_path) and file.split('.')[-1] in ['xls', 'xlsx']: | ||
191 | + if '~$' not in file: | ||
192 | + sure_lst.append(file) | ||
193 | + else: | ||
194 | + err_lst.append(file) | ||
195 | + return sure_lst, err_lst | ||
196 | + | ||
197 | + | ||
198 | +def clean_up_file(tenant_type, sure_lst, err_lst): | ||
199 | + """清理并插入文件""" | ||
200 | + for file in sure_lst: | ||
201 | + if "~$" + file in err_lst: | ||
202 | + logger.error("文件为打开状态无法上传:" + file) | ||
203 | + insert_tasks([file], tenant_type, status=STATUS_FAIL, comment='文件为打开状态无法办理') | ||
204 | + elif '社保' not in file and '工资' not in file: | ||
205 | + insert_tasks([file], tenant_type, status=STATUS_FAIL, comment='文件名不识别') | ||
206 | + elif '社保' in file and '工资' in file: | ||
207 | + insert_tasks([file], tenant_type, status=STATUS_FAIL, comment='文件名不能同时包含社保和工资') | ||
208 | + else: | ||
209 | + insert_tasks([file], tenant_type, status=STATUS_AVAIL, comment='') | ||
210 | + return list_do_task() | ||
211 | + | ||
212 | + | ||
213 | +def insert_tasks(file_list, tenant_type, status=STATUS_AVAIL, comment=''): | ||
214 | + """把任务插入到数据库中""" | ||
215 | + if not file_list: | ||
216 | + return | ||
217 | + for file in file_list: | ||
218 | + task_id = str(get_timestamp()) | ||
219 | + bus_type = '社保' if '社保' in file else '工资' | ||
220 | + plat_type = 'HR' if tenant_type == '1' else 'HRO' | ||
221 | + task_time = get_datetime() | ||
222 | + params = (task_id, file, bus_type, plat_type, task_time, status, comment) | ||
223 | + DBClass().execute('INSERT INTO task VALUES(?, ?, ?, ?, ?, ?, ?)', params) | ||
224 | + time.sleep(1) | ||
225 | + | ||
226 | + | ||
227 | +def move_del_file(work_path, file, types, task_id): | ||
228 | + """移动和删除传成功的文件到已完成文件夹中""" | ||
229 | + finished_floder = "" | ||
230 | + data_floder = time.strftime("%Y%m%d", time.localtime()) | ||
231 | + if types == TASK_TYPE_INSURANCE: | ||
232 | + finished_floder = work_path + "/" + "已完成(社保)" | ||
233 | + elif types == TASK_TYPE_SALARY: | ||
234 | + finished_floder = work_path + "/" + "已完成(工资)" | ||
235 | + try: | ||
236 | + if not os.path.exists(finished_floder): | ||
237 | + os.mkdir(finished_floder) | ||
238 | + finished_floder += "/" + data_floder | ||
239 | + if not os.path.exists(finished_floder): | ||
240 | + os.mkdir(finished_floder) | ||
241 | + except Exception as e: | ||
242 | + logger.error(str(e)) | ||
243 | + return | ||
244 | + | ||
245 | + src = work_path + "/" + file | ||
246 | + finish_src = finished_floder + "/" + file | ||
247 | + if os.path.exists(finish_src): | ||
248 | + try: | ||
249 | + time_floder = time.strftime("%Y%m%d-%H%M%S", time.localtime()) | ||
250 | + lst = file.split(".") | ||
251 | + new_file = ''.join(lst[:-1]) + "_" + time_floder + "." + lst[-1] | ||
252 | + new_src = work_path + "/" + new_file | ||
253 | + os.rename(src, new_src) | ||
254 | + shutil.move(new_src, finished_floder) | ||
255 | + DBClass().execute("UPDATE task SET filename = ? WHERE task_id = ?", (new_file, task_id)) | ||
256 | + except Exception as e: | ||
257 | + logger.error(str(e)) | ||
258 | + return | ||
259 | + else: | ||
260 | + shutil.move(src, finished_floder) | ||
261 | + | ||
262 | + | ||
263 | +def batch_update_files(work_path, file_list, tenant_id, tenant_type): | ||
264 | + """批量上传文件""" | ||
265 | + ctx = { | ||
266 | + "access_token": "", | ||
267 | + "refresh_token": "", | ||
268 | + "tenant_id": tenant_id | ||
269 | + } | ||
270 | + result = DBClass().execute('SELECT * FROM account') | ||
271 | + if result == DB_STATUS_FAIL or not result: | ||
272 | + return | ||
273 | + access_token, refresh_tokens, err, t_info = get_token_by_password(result[0][0], result[0][1], tenant_id, tenant_type) | ||
274 | + ctx['access_token'] = access_token | ||
275 | + ctx['refresh_token'] = refresh_tokens | ||
276 | + if err != "": | ||
277 | + _access_token, _refresh_token, _err, t_info = refresh_token(ctx['refresh_token'], ctx['tenant_id'], tenant_type) | ||
278 | + ctx['access_token'] = _access_token | ||
279 | + ctx['refresh_token'] = _refresh_token | ||
280 | + if _err != "": | ||
281 | + return | ||
282 | + | ||
283 | + for file in file_list: | ||
284 | + if file[5] == STATUS_FAIL: | ||
285 | + continue | ||
286 | + update_task(file[0], STATUS_RUNNING, '') | ||
287 | + local_path = work_path + "/" + file[1] | ||
288 | + if "社保" in file[1]: | ||
289 | + types = TASK_TYPE_INSURANCE | ||
290 | + elif "工资" in file[1]: | ||
291 | + types = TASK_TYPE_SALARY | ||
292 | + else: | ||
293 | + logger.error("文件名不识别:" + file[1]) | ||
294 | + update_task(file[0], STATUS_FAIL, '文件名不识别') | ||
295 | + continue | ||
296 | + | ||
297 | + try: | ||
298 | + code, object_path = upload_file(ctx, local_path, tenant_type, file[1]) | ||
299 | + logger.info("上传结果:" + str(code) + ", 存储路径:" + object_path) | ||
300 | + if code != 200: | ||
301 | + update_task(file[0], STATUS_FAIL, '上传文件失败') | ||
302 | + continue | ||
303 | + | ||
304 | + status, reason = update_object_path(ctx, tenant_type, object_path, types, file[1]) | ||
305 | + if status: | ||
306 | + logger.info("上传成功:" + file[1]) | ||
307 | + move_del_file(work_path, file[1], types, file[0]) | ||
308 | + update_task(file[0], STATUS_SUCCESS, reason) | ||
309 | + else: | ||
310 | + update_task(file[0], STATUS_FAIL, reason) | ||
311 | + except Exception as e: | ||
312 | + logger.error(str(e)) | ||
313 | + update_task(file[0], STATUS_FAIL, '网络或服务器异常') | ||
314 | + | ||
315 | + | ||
316 | +def update_task(task_id, status, comment=''): | ||
317 | + """更新任务状态的函数""" | ||
318 | + sql = "UPDATE task SET status = ?, comment = ? WHERE task_id = ?" | ||
319 | + params = (status, comment, task_id) | ||
320 | + DBClass().execute(sql, params) | ||
321 | + | ||
322 | + | ||
323 | +def reg_auto_start(path): | ||
324 | + """设置开启自启动写入注册表""" | ||
325 | + runpath = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run' | ||
326 | + # runpath = 'Software\\Microsoft\\Windows\\CurrentVersion\\Run' | ||
327 | + hKey = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, runpath, 0, win32con.KEY_WRITE | win32con.KEY_WOW64_64KEY) | ||
328 | + win32api.RegSetValueEx(hKey, 'taxbot', 0, win32con.REG_SZ, path) | ||
329 | + win32api.RegCloseKey(hKey) | ||
330 | + | ||
331 | + | ||
332 | +def crease_shoutcut(): | ||
333 | + """创建自启动快捷方式到启动项""" | ||
334 | + target = sys.argv[0] | ||
335 | + title = '智能数据助手' | ||
336 | + file = path.basename(target) | ||
337 | + fname = path.splitext(file)[0] | ||
338 | + root = path.dirname(target) | ||
339 | + shout_path = path.join(winshell.startup(), fname + '.lnk') | ||
340 | + if not os.path.exists(shout_path): | ||
341 | + winshell.CreateShortcut(StartIn=root, Path=shout_path, Target=target, | ||
342 | + Icon=(target, 0), Description=title) | ||
343 | + | ||
344 | + | ||
345 | +def list_do_task(): | ||
346 | + """获取待办任务列表""" | ||
347 | + try: | ||
348 | + result = DBClass().execute('SELECT * FROM task WHERE status != ? ORDER BY task_id ASC', (STATUS_SUCCESS, )) | ||
349 | + if result == DB_STATUS_FAIL: | ||
350 | + logger.error("读写数据库数据错误") | ||
351 | + return None | ||
352 | + return result | ||
353 | + except sqlite3.Error as e: | ||
354 | + logger.error('获取代办理任务数据失败: %s' % (str(e))) | ||
355 | + | ||
356 | + return None | ||
357 | + | ||
358 | + | ||
359 | +def list_doed_task(): | ||
360 | + """获取已办任务列表数据""" | ||
361 | + try: | ||
362 | + result = DBClass().execute('SELECT * FROM task WHERE status = ? ORDER BY task_id DESC', (STATUS_SUCCESS, )) | ||
363 | + if result == DB_STATUS_FAIL: | ||
364 | + logger.error("读写数据库数据错误") | ||
365 | + return None | ||
366 | + return result | ||
367 | + except sqlite3.Error as e: | ||
368 | + logger.error('获取已办理任务数据错误: %s' % (str(e))) | ||
369 | + | ||
370 | + return None | ||
371 | + | ||
372 | + | ||
373 | +def get_userinfo(): | ||
374 | + """获取登录用户信息函数""" | ||
375 | + try: | ||
376 | + result = DBClass().execute('SELECT * FROM account') | ||
377 | + if result == DB_STATUS_FAIL: | ||
378 | + logger.error("读写数据库数据错误") | ||
379 | + return None | ||
380 | + return result | ||
381 | + except sqlite3.Error as e: | ||
382 | + logger.error('获取用户信息错误 %s' % (str(e))) | ||
383 | + | ||
384 | + return None | ||
385 | + | ||
386 | + | ||
387 | +def get_socket(HOST, PORT): | ||
388 | + """给应用程序注册socket端口""" | ||
389 | + try: | ||
390 | + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
391 | + s.bind((HOST, PORT)) | ||
392 | + s.listen(2) | ||
393 | + return s | ||
394 | + except Exception as e: | ||
395 | + logger.error(str(e)) | ||
396 | + return None | ||
397 | + | ||
398 | + | ||
399 | +def port_is_use(HOST, PORT): | ||
400 | + """检查端口是否被占用""" | ||
401 | + try: | ||
402 | + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
403 | + s.connect((HOST, PORT)) | ||
404 | + s.shutdown(2) | ||
405 | + logger.info('端口 %s 是被占用的' % str(PORT)) | ||
406 | + return True | ||
407 | + except Exception as e: | ||
408 | + logger.error(str(e)) | ||
409 | + return False | ||
410 | + | ||
411 | + | ||
412 | +def socket_listen(s): | ||
413 | + while True: | ||
414 | + connsd, addr = s.accept() | ||
415 | + logger.info("连接对象:%s, 请求地址:%s" % (str(connsd), addr)) | ||
416 | + time.sleep(1) | ||
417 | + s.close() | ||
418 | + logger.info("socket对象关闭") | ||
419 | + | ||
420 | + | ||
421 | +def check_system(): | ||
422 | + """检查操作系统类型""" | ||
423 | + try: | ||
424 | + sys_str = platform.platform() | ||
425 | + if not sys_str: | ||
426 | + if 'Windows-7' in sys_str: | ||
427 | + return 7 | ||
428 | + elif 'Windows-10' in sys_str: | ||
429 | + return 10 | ||
430 | + except Exception as e: | ||
431 | + logger.error(str(e)) | ||
432 | + | ||
433 | + return 10 |
taxbot/forms/__init__.py
0 → 100644
taxbot/forms/floderfrom.py
0 → 100644
1 | +# -*- coding: utf-8 -*- | ||
2 | +import os | ||
3 | +import win32com.client | ||
4 | +from PyQt5 import QtCore, QtGui, QtWidgets | ||
5 | +from PyQt5.QtWidgets import QMainWindow, QMessageBox, QFileDialog | ||
6 | +from PyQt5.QtCore import Qt | ||
7 | +from common.dbutils import * | ||
8 | +from common.constant import * | ||
9 | +from qrc import icon | ||
10 | + | ||
11 | + | ||
12 | +class Ui_FloderWindow(object): | ||
13 | + def __init__(self, main_form): | ||
14 | + self.FloderWindow = QMainWindow() | ||
15 | + self.font = QtGui.QFont() | ||
16 | + self.font.setFamily("微软雅黑") | ||
17 | + self.font.setPointSize(9) | ||
18 | + self.main_form = main_form | ||
19 | + | ||
20 | + def setupUi(self): | ||
21 | + self.FloderWindow.setObjectName("FloderWindow") | ||
22 | + self.FloderWindow.setFixedSize(340, 150) | ||
23 | + self.FloderWindow.setWindowFlags(Qt.WindowStaysOnTopHint) | ||
24 | + self.FloderWindow.setWindowFlags(Qt.WindowMinimizeButtonHint) | ||
25 | + | ||
26 | + icon = QtGui.QIcon() | ||
27 | + icon.addPixmap(QtGui.QPixmap(":/icon/imgs/logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
28 | + self.FloderWindow.setWindowIcon(icon) | ||
29 | + self.centralwidget = QtWidgets.QWidget(self.FloderWindow) | ||
30 | + self.centralwidget.setObjectName("centralwidget") | ||
31 | + self.lineEdit = QtWidgets.QLineEdit(self.centralwidget) | ||
32 | + self.lineEdit.setGeometry(QtCore.QRect(30, 30, 220, 26)) | ||
33 | + self.lineEdit.setFont(self.font) | ||
34 | + self.lineEdit.setReadOnly(True) | ||
35 | + | ||
36 | + self.pushButton = QtWidgets.QPushButton(self.centralwidget) | ||
37 | + self.pushButton.setGeometry(QtCore.QRect(260, 30, 50, 26)) | ||
38 | + self.pushButton.setFont(self.font) | ||
39 | + self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) | ||
40 | + self.pushButton_2.setGeometry(QtCore.QRect(197, 90, 75, 26)) | ||
41 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) | ||
42 | + sizePolicy.setHorizontalStretch(0) | ||
43 | + sizePolicy.setVerticalStretch(0) | ||
44 | + sizePolicy.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth()) | ||
45 | + self.pushButton_2.setSizePolicy(sizePolicy) | ||
46 | + self.pushButton_2.setFont(self.font) | ||
47 | + | ||
48 | + self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget) | ||
49 | + self.pushButton_3.setGeometry(QtCore.QRect(60, 90, 75, 26)) | ||
50 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) | ||
51 | + sizePolicy.setHorizontalStretch(0) | ||
52 | + sizePolicy.setVerticalStretch(0) | ||
53 | + sizePolicy.setHeightForWidth(self.pushButton_3.sizePolicy().hasHeightForWidth()) | ||
54 | + self.pushButton_3.setSizePolicy(sizePolicy) | ||
55 | + self.pushButton_3.setFont(self.font) | ||
56 | + self.FloderWindow.setCentralWidget(self.centralwidget) | ||
57 | + | ||
58 | + self.retranslateUi(self.FloderWindow) | ||
59 | + self.__init_click() | ||
60 | + | ||
61 | + QtCore.QMetaObject.connectSlotsByName(self.FloderWindow) | ||
62 | + | ||
63 | + def retranslateUi(self, MainWindow): | ||
64 | + _translate = QtCore.QCoreApplication.translate | ||
65 | + MainWindow.setWindowTitle(_translate("FloderWindow", "选择工作目录")) | ||
66 | + self.lineEdit.setPlaceholderText(_translate("FloderWindow", "选择工作目录文件夹")) | ||
67 | + self.pushButton.setText(_translate("FloderWindow", "选择")) | ||
68 | + self.pushButton_2.setText(_translate("FloderWindow", "保存")) | ||
69 | + self.pushButton_3.setText(_translate("FloderWindow", "取消")) | ||
70 | + | ||
71 | + def __init_click(self): | ||
72 | + self.pushButton.clicked.connect(self.__select) | ||
73 | + self.pushButton_2.setShortcut('return') | ||
74 | + self.pushButton_3.clicked.connect(self.__exit) | ||
75 | + self.pushButton_3.setShortcut('Esc') | ||
76 | + self.pushButton_2.clicked.connect(self.save) | ||
77 | + | ||
78 | + def __select(self): | ||
79 | + """选择工作目录文件夹""" | ||
80 | + path = os.getcwd() | ||
81 | + try: | ||
82 | + path = QFileDialog.getExistingDirectory(parent=self.FloderWindow, caption='选择工作目录', directory=os.getcwd()) | ||
83 | + except Exception as e: | ||
84 | + print(str(e)) | ||
85 | + | ||
86 | + self.lineEdit.setText(path) | ||
87 | + | ||
88 | + def __exit(self): | ||
89 | + """退出启动窗口事件""" | ||
90 | + result = QMessageBox.question(self.FloderWindow, '提示', '确定要取消选择工作目录吗?', QMessageBox.Yes | QMessageBox.No) | ||
91 | + if result == 16384: | ||
92 | + self.FloderWindow.close() | ||
93 | + return True | ||
94 | + return False | ||
95 | + | ||
96 | + def save(self): | ||
97 | + path = self.lineEdit.text() | ||
98 | + if not path: | ||
99 | + QMessageBox.warning(self.FloderWindow, '消息', '请选择工作目录!') | ||
100 | + return | ||
101 | + | ||
102 | + result = DBClass().execute('UPDATE account SET ac_floder = ?', (path, )) | ||
103 | + if result == DB_STATUS_FAIL: | ||
104 | + QMessageBox.warning(self.FloderWindow, '消息', '保存工作目录失败!') | ||
105 | + else: | ||
106 | + self.FloderWindow.close() | ||
107 | + self.main_form.mainform_show() |
taxbot/forms/loginform.py
0 → 100644
1 | +# -*- coding: utf-8 -*- | ||
2 | +import re | ||
3 | +import time | ||
4 | +from PyQt5 import QtCore, QtGui, QtWidgets | ||
5 | +from PyQt5.QtWidgets import QMainWindow, QMessageBox | ||
6 | +from PyQt5.QtCore import Qt | ||
7 | +from common.dbutils import * | ||
8 | +from common.constant import * | ||
9 | +from common.api import * | ||
10 | +from threading import Thread | ||
11 | +from queue import Queue | ||
12 | +from qrc import icon | ||
13 | + | ||
14 | +q_login = Queue() | ||
15 | + | ||
16 | + | ||
17 | +class Ui_LoginWindow(object): | ||
18 | + def __init__(self): | ||
19 | + self.LoginWindow = QMainWindow() | ||
20 | + self.font = QtGui.QFont() | ||
21 | + self.font.setFamily("微软雅黑") | ||
22 | + self.font.setPointSize(10) | ||
23 | + self.centralwidget = QtWidgets.QWidget(self.LoginWindow) | ||
24 | + self._translate = QtCore.QCoreApplication.translate | ||
25 | + | ||
26 | + def __init_window_ui(self): | ||
27 | + """初始化窗口框架""" | ||
28 | + self.LoginWindow.setObjectName("LoginWindow") | ||
29 | + self.LoginWindow.setFixedSize(320, 200) | ||
30 | + self.LoginWindow.setWindowFlags(Qt.WindowStaysOnTopHint) | ||
31 | + self.LoginWindow.setWindowFlags(Qt.WindowMinimizeButtonHint) | ||
32 | + # self.LoginWindow.setWindowFlags(Qt.FramelessWindowHint) | ||
33 | + icon = QtGui.QIcon() | ||
34 | + icon.addPixmap(QtGui.QPixmap(":/icon/imgs/logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
35 | + self.LoginWindow.setWindowIcon(icon) | ||
36 | + self.LoginWindow.setWindowTitle(self._translate("LoginWindow", "智能数据助手")) | ||
37 | + | ||
38 | + def __init_ui(self): | ||
39 | + """初始化标签界面""" | ||
40 | + self.layoutWidget = QtWidgets.QWidget(self.centralwidget) | ||
41 | + self.layoutWidget.setGeometry(QtCore.QRect(40, 25, 241, 151)) | ||
42 | + self.layoutWidget.setObjectName("layoutWidget") | ||
43 | + # self.layoutWidget.setStyleSheet("background-image: url(:/icon/imgs/bg.png);") | ||
44 | + self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget) | ||
45 | + self.gridLayout.setSpacing(5) | ||
46 | + | ||
47 | + self.horizontalLayout = QtWidgets.QHBoxLayout() | ||
48 | + self.label = QtWidgets.QLabel(self.layoutWidget) | ||
49 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) | ||
50 | + sizePolicy.setHorizontalStretch(0) | ||
51 | + sizePolicy.setVerticalStretch(0) | ||
52 | + sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) | ||
53 | + self.label.setSizePolicy(sizePolicy) | ||
54 | + self.label.setFont(self.font) | ||
55 | + self.label.setText(self._translate("LoginWindow", "账号: ")) | ||
56 | + self.horizontalLayout.addWidget(self.label) | ||
57 | + | ||
58 | + self.lineEdit = QtWidgets.QLineEdit(self.layoutWidget) | ||
59 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) | ||
60 | + sizePolicy.setHorizontalStretch(0) | ||
61 | + sizePolicy.setVerticalStretch(0) | ||
62 | + sizePolicy.setHeightForWidth(self.lineEdit.sizePolicy().hasHeightForWidth()) | ||
63 | + self.lineEdit.setSizePolicy(sizePolicy) | ||
64 | + self.lineEdit.setMinimumSize(QtCore.QSize(0, 25)) | ||
65 | + self.font.setPointSize(9) | ||
66 | + self.lineEdit.setFont(self.font) | ||
67 | + self.lineEdit.setMaxLength(11) | ||
68 | + self.lineEdit.setPlaceholderText(self._translate("LoginWindow", "请输入手机号")) | ||
69 | + self.lineEdit.setClearButtonEnabled(True) | ||
70 | + self.horizontalLayout.addWidget(self.lineEdit) | ||
71 | + self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1) | ||
72 | + | ||
73 | + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() | ||
74 | + self.label_2 = QtWidgets.QLabel(self.layoutWidget) | ||
75 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) | ||
76 | + sizePolicy.setHorizontalStretch(0) | ||
77 | + sizePolicy.setVerticalStretch(0) | ||
78 | + sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth()) | ||
79 | + self.label_2.setSizePolicy(sizePolicy) | ||
80 | + self.font.setPointSize(10) | ||
81 | + self.label_2.setFont(self.font) | ||
82 | + self.label_2.setText(self._translate("LoginWindow", "密码: ")) | ||
83 | + self.horizontalLayout_2.addWidget(self.label_2) | ||
84 | + | ||
85 | + self.lineEdit_2 = QtWidgets.QLineEdit(self.layoutWidget) | ||
86 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) | ||
87 | + sizePolicy.setHorizontalStretch(0) | ||
88 | + sizePolicy.setVerticalStretch(0) | ||
89 | + sizePolicy.setHeightForWidth(self.lineEdit_2.sizePolicy().hasHeightForWidth()) | ||
90 | + self.lineEdit_2.setSizePolicy(sizePolicy) | ||
91 | + self.lineEdit_2.setMinimumSize(QtCore.QSize(0, 25)) | ||
92 | + self.font.setPointSize(9) | ||
93 | + self.lineEdit_2.setFont(self.font) | ||
94 | + self.lineEdit_2.setPlaceholderText(self._translate("LoginWindow", "请输入密码")) | ||
95 | + self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password) | ||
96 | + self.lineEdit_2.setMaxLength(16) | ||
97 | + self.lineEdit_2.setClearButtonEnabled(True) | ||
98 | + self.horizontalLayout_2.addWidget(self.lineEdit_2) | ||
99 | + self.gridLayout.addLayout(self.horizontalLayout_2, 1, 0, 1, 1) | ||
100 | + | ||
101 | + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() | ||
102 | + self.horizontalLayout_3.setContentsMargins(-1, 10, -1, -1) | ||
103 | + self.horizontalLayout_3.setSpacing(50) | ||
104 | + self.pushButton = QtWidgets.QPushButton(self.layoutWidget) | ||
105 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) | ||
106 | + sizePolicy.setHorizontalStretch(0) | ||
107 | + sizePolicy.setVerticalStretch(0) | ||
108 | + sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth()) | ||
109 | + self.pushButton.setSizePolicy(sizePolicy) | ||
110 | + self.font.setPointSize(9) | ||
111 | + self.pushButton.setFont(self.font) | ||
112 | + self.pushButton.setText(self._translate("LoginWindow", "取消")) | ||
113 | + self.horizontalLayout_3.addWidget(self.pushButton) | ||
114 | + | ||
115 | + self.pushButton_2 = QtWidgets.QPushButton(self.layoutWidget) | ||
116 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) | ||
117 | + sizePolicy.setHorizontalStretch(0) | ||
118 | + sizePolicy.setVerticalStretch(0) | ||
119 | + sizePolicy.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth()) | ||
120 | + self.pushButton_2.setSizePolicy(sizePolicy) | ||
121 | + self.pushButton_2.setFont(self.font) | ||
122 | + self.pushButton_2.setText(self._translate("LoginWindow", "登录")) | ||
123 | + self.horizontalLayout_3.addWidget(self.pushButton_2) | ||
124 | + self.gridLayout.addLayout(self.horizontalLayout_3, 2, 0, 1, 1) | ||
125 | + | ||
126 | + # self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget) | ||
127 | + # self.pushButton_3.setGeometry(QtCore.QRect(280, 0, 36, 23)) | ||
128 | + # self.pushButton_3.setMinimumSize(QtCore.QSize(20, 20)) | ||
129 | + # self.pushButton_3.setText("") | ||
130 | + # icon = QtGui.QIcon() | ||
131 | + # icon.addPixmap(QtGui.QPixmap(":/icon/imgs/close.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
132 | + # self.pushButton_3.setIcon(icon) | ||
133 | + # self.pushButton_3.setIconSize(QtCore.QSize(12, 12)) | ||
134 | + # | ||
135 | + # self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget) | ||
136 | + # self.pushButton_4.setGeometry(QtCore.QRect(240, 0, 36, 23)) | ||
137 | + # self.pushButton_4.setMinimumSize(QtCore.QSize(20, 20)) | ||
138 | + # self.pushButton_4.setText("") | ||
139 | + # icon1 = QtGui.QIcon() | ||
140 | + # icon1.addPixmap(QtGui.QPixmap(":/icon/imgs/min.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
141 | + # self.pushButton_4.setIcon(icon1) | ||
142 | + # self.pushButton_4.setIconSize(QtCore.QSize(14, 14)) | ||
143 | + | ||
144 | + def __init_click(self): | ||
145 | + self.pushButton.clicked.connect(self.__exit) | ||
146 | + self.pushButton.setShortcut('Esc') | ||
147 | + self.pushButton_2.setShortcut('return') | ||
148 | + # self.pushButton_3.clicked.connect(self.__exit) | ||
149 | + # self.pushButton_4.clicked.connect(self.__min) | ||
150 | + | ||
151 | + def __exit(self): | ||
152 | + """退出启动窗口事件""" | ||
153 | + result = QMessageBox.question(self.LoginWindow, '提示', '确定要退出系统吗?', QMessageBox.Yes | QMessageBox.No) | ||
154 | + if result == 16384: | ||
155 | + self.LoginWindow.close() | ||
156 | + return True | ||
157 | + return False | ||
158 | + | ||
159 | + def login(self, floder_form, tenant_id, tenant_type): | ||
160 | + account = self.lineEdit.text() | ||
161 | + passwd = self.lineEdit_2.text() | ||
162 | + if not account or len(account) != 11: | ||
163 | + QMessageBox.warning(self.LoginWindow, '消息', '账号长度必须为11位手机号。') | ||
164 | + elif not re.findall('^\d{11}$', account): | ||
165 | + QMessageBox.warning(self.LoginWindow, '消息', '输入的手机号不正确。') | ||
166 | + elif not re.findall('^1[356789]\d{9}$', account): | ||
167 | + QMessageBox.warning(self.LoginWindow, '消息', '手机号输入有误') | ||
168 | + elif not passwd or len(passwd) < 6: | ||
169 | + QMessageBox.warning(self.LoginWindow, '消息', '密码长度不能小于6位。') | ||
170 | + else: | ||
171 | + global q_login | ||
172 | + Thread(target=self.__start_login, args=(account, passwd, tenant_id, tenant_type, q_login)).start() | ||
173 | + code, err = q_login.get() | ||
174 | + | ||
175 | + if code in [404, 1010, 500, 400]: | ||
176 | + QMessageBox.warning(self.LoginWindow, '消息', err) | ||
177 | + | ||
178 | + if code == 200: | ||
179 | + self.LoginWindow.close() | ||
180 | + floder_form.FloderWindow.show() | ||
181 | + | ||
182 | + def __start_login(self, account, passwd, tenant_id, tenant_type, q): | ||
183 | + """处理登录接口处理函数""" | ||
184 | + try: | ||
185 | + access_token, refresh_token, err, t_info = get_token_by_password(account, passwd, tenant_id, tenant_type) | ||
186 | + if err != '': | ||
187 | + logger.error("登录失败: " + err) | ||
188 | + t = (404, err) | ||
189 | + q.put(t) | ||
190 | + else: | ||
191 | + company = t_info[0] | ||
192 | + username = t_info[1] | ||
193 | + play_typt = t_info[2] | ||
194 | + result = DBClass().execute('INSERT INTO account VALUES(?, ?, ?, ?, ?, ?)', (account, passwd, '', company, username, play_typt)) | ||
195 | + if result == DB_STATUS_FAIL: | ||
196 | + logger.error("读写数据库数据错误") | ||
197 | + t = (1010, '保存登录信息失败,请稍后再试!') | ||
198 | + q.put(t) | ||
199 | + else: | ||
200 | + logger.error("登录成功") | ||
201 | + t = (200, '登录成功!') | ||
202 | + q.put(t) | ||
203 | + except Exception as e: | ||
204 | + logger.error(str(e)) | ||
205 | + t = (500, '网络或服务器异常,请稍后再试!') | ||
206 | + q.put(t) | ||
207 | + | ||
208 | + def __min(self): | ||
209 | + """窗口最小化到托盘""" | ||
210 | + self.LoginWindow.showMinimized() | ||
211 | + | ||
212 | + def setupUi(self): | ||
213 | + self.__init_window_ui() | ||
214 | + self.__init_ui() | ||
215 | + self.__init_click() | ||
216 | + | ||
217 | + self.LoginWindow.setCentralWidget(self.centralwidget) | ||
218 | + QtCore.QMetaObject.connectSlotsByName(self.LoginWindow) | ||
219 | + | ||
220 | + | ||
221 | + | ||
222 | + | ||
223 | + | ||
224 | + | ||
225 | + |
taxbot/forms/mainform.py
0 → 100644
1 | +# -*- coding: utf-8 -*- | ||
2 | +import re | ||
3 | +import time | ||
4 | +import queue | ||
5 | +import json | ||
6 | +from PyQt5 import QtCore, QtGui, QtWidgets | ||
7 | +from PyQt5.QtGui import QBrush, QColor | ||
8 | +from PyQt5.QtWidgets import * | ||
9 | +from PyQt5.QtCore import * | ||
10 | +from common.utils import * | ||
11 | +from threading import Thread | ||
12 | +from qrc import icon | ||
13 | + | ||
14 | +q_do_task = queue.Queue() | ||
15 | +q_doed_task = queue.Queue() | ||
16 | +q_start = queue.Queue() | ||
17 | +q_task = queue.Queue() | ||
18 | + | ||
19 | +q_floder = queue.Queue() # 是否工作目录有效 | ||
20 | +q_files = queue.Queue() # 是否有可办理得任务表格 | ||
21 | + | ||
22 | + | ||
23 | +class UpdateDoTask(QThread): | ||
24 | + update_date = pyqtSignal(str) | ||
25 | + | ||
26 | + def run(self): | ||
27 | + while True: | ||
28 | + if q_do_task.get(): | ||
29 | + tasks = list_do_task() | ||
30 | + if not tasks or len(tasks) == 0: | ||
31 | + data1 = {} | ||
32 | + self.update_date.emit(json.dumps(data1)) # 发射信号 | ||
33 | + else: | ||
34 | + row = 0 | ||
35 | + for task in tasks: | ||
36 | + data = {'cnt': len(tasks), 'row': row, 'task_id': task[0], 'filename': task[1], | ||
37 | + 'bus_type': task[2], 'plat_type': task[3], 'task_time': task[4], 'comment': task[6]} | ||
38 | + if task[5] == STATUS_AVAIL or task[5] == '': | ||
39 | + data['status'] = '等待办理' | ||
40 | + elif task[5] == STATUS_RUNNING: | ||
41 | + data['status'] = '正在办理' | ||
42 | + elif task[5] == STATUS_SUCCESS: | ||
43 | + data['status'] = '办理成功' | ||
44 | + elif task[5] == STATUS_FAIL: | ||
45 | + data['status'] = '办理失败' | ||
46 | + self.update_date.emit(json.dumps(data)) # 发射信号 | ||
47 | + row += 1 | ||
48 | + time.sleep(1) | ||
49 | + | ||
50 | + | ||
51 | +class UpdateDoedTask(QThread): | ||
52 | + update_date = pyqtSignal(str) | ||
53 | + | ||
54 | + def run(self): | ||
55 | + while True: | ||
56 | + if q_doed_task.get(): | ||
57 | + tasks = list_doed_task() | ||
58 | + if not tasks or len(tasks) == 0: | ||
59 | + data1 = {} | ||
60 | + self.update_date.emit(json.dumps(data1)) # 发射信号 | ||
61 | + else: | ||
62 | + row = 0 | ||
63 | + for task in tasks: | ||
64 | + data = {'cnt': len(tasks), 'row': row, 'task_id': task[0], 'filename': task[1], | ||
65 | + 'bus_type': task[2], 'plat_type': task[3], 'task_time': task[4], 'comment': task[6]} | ||
66 | + if task[5] == STATUS_AVAIL or task[5] == '': | ||
67 | + data['status'] = '等待办理' | ||
68 | + elif task[5] == STATUS_RUNNING: | ||
69 | + data['status'] = '正在办理' | ||
70 | + elif task[5] == STATUS_SUCCESS: | ||
71 | + data['status'] = '办理成功' | ||
72 | + elif task[5] == STATUS_FAIL: | ||
73 | + data['status'] = '办理失败' | ||
74 | + self.update_date.emit(json.dumps(data)) # 发射信号 | ||
75 | + row += 1 | ||
76 | + time.sleep(1) | ||
77 | + | ||
78 | + | ||
79 | +class myLable(QLabel): | ||
80 | + def __init__(self, parent=None): | ||
81 | + super(myLable, self).__init__(parent) | ||
82 | + | ||
83 | + def mousePressEvent(self, QMouseEvent): | ||
84 | + self.setStyleSheet("color: rgb(255, 0, 0);") | ||
85 | + | ||
86 | + def mouseReleaseEvent(self, QMouseEvent): | ||
87 | + self.setStyleSheet("color: rgb(85, 0, 255);") | ||
88 | + | ||
89 | + | ||
90 | +class Ui_MainWindow(object): | ||
91 | + def __init__(self): | ||
92 | + self.MainWindow = QMainWindow() | ||
93 | + self.MainWindow.setWindowFlags(Qt.WindowStaysOnTopHint) | ||
94 | + # self.MainWindow.setWindowFlags(Qt.WindowMinMaxButtonsHint) | ||
95 | + self._translate = QtCore.QCoreApplication.translate | ||
96 | + self.cur_btn = None | ||
97 | + self.work_path = '' | ||
98 | + self.is_refresh = False | ||
99 | + self.sure_lst = [] | ||
100 | + self.err_lst = [] | ||
101 | + self.sys_type = check_system() | ||
102 | + self.MainObjectName = 'MainWindow' | ||
103 | + | ||
104 | + def setupUi(self): | ||
105 | + self.MainWindow.setObjectName("MainWindow") | ||
106 | + self.MainWindow.resize(950, 600) | ||
107 | + self.MainWindow.setMinimumSize(QtCore.QSize(900, 600)) | ||
108 | + icon = QtGui.QIcon() | ||
109 | + icon.addPixmap(QtGui.QPixmap(":/icon/imgs/logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
110 | + self.MainWindow.setWindowIcon(icon) | ||
111 | + self.MainWindow.setAutoFillBackground(False) | ||
112 | + self.MainWindow.setStyleSheet("") | ||
113 | + self.centralwidget = QtWidgets.QWidget(self.MainWindow) | ||
114 | + self.centralwidget.setObjectName("centralwidget") | ||
115 | + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget) | ||
116 | + self.verticalLayout_2.setContentsMargins(10, 0, 10, 0) | ||
117 | + self.verticalLayout_2.setSpacing(0) | ||
118 | + self.verticalLayout_2.setObjectName("verticalLayout_2") | ||
119 | + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() | ||
120 | + self.horizontalLayout_2.setSpacing(0) | ||
121 | + self.horizontalLayout_2.setObjectName("horizontalLayout_2") | ||
122 | + self.frame = QtWidgets.QFrame(self.centralwidget) | ||
123 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) | ||
124 | + sizePolicy.setHorizontalStretch(0) | ||
125 | + sizePolicy.setVerticalStretch(0) | ||
126 | + sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) | ||
127 | + self.frame.setSizePolicy(sizePolicy) | ||
128 | + self.frame.setMinimumSize(QtCore.QSize(0, 60)) | ||
129 | + font = QtGui.QFont() | ||
130 | + font.setFamily("宋体") | ||
131 | + font.setPointSize(11) | ||
132 | + self.frame.setFont(font) | ||
133 | + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) | ||
134 | + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) | ||
135 | + self.frame.setObjectName("frame") | ||
136 | + self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame) | ||
137 | + self.horizontalLayout.setContentsMargins(0, 0, 0, 8) | ||
138 | + self.horizontalLayout.setSpacing(0) | ||
139 | + self.horizontalLayout.setObjectName("horizontalLayout") | ||
140 | + self.verticalLayout = QtWidgets.QVBoxLayout() | ||
141 | + self.verticalLayout.setSpacing(0) | ||
142 | + self.verticalLayout.setObjectName("verticalLayout") | ||
143 | + self.label = myLable(self.frame) | ||
144 | + # self.label = QtWidgets.QLabel(self.frame) | ||
145 | + font = QtGui.QFont() | ||
146 | + font.setFamily("宋体") | ||
147 | + font.setPointSize(16) | ||
148 | + font.setBold(True) | ||
149 | + font.setWeight(75) | ||
150 | + self.label.setFont(font) | ||
151 | + self.label.setStyleSheet("color: rgb(85, 0, 255);") | ||
152 | + self.label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) | ||
153 | + self.label.setObjectName("label") | ||
154 | + self.verticalLayout.addWidget(self.label) | ||
155 | + self.label_2 = QtWidgets.QLabel(self.frame) | ||
156 | + font = QtGui.QFont() | ||
157 | + font.setFamily("宋体") | ||
158 | + font.setPointSize(10) | ||
159 | + font.setBold(False) | ||
160 | + font.setWeight(50) | ||
161 | + self.label_2.setFont(font) | ||
162 | + self.label_2.setStyleSheet("") | ||
163 | + self.label_2.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) | ||
164 | + self.label_2.setObjectName("label_2") | ||
165 | + self.verticalLayout.addWidget(self.label_2) | ||
166 | + self.verticalLayout.setStretch(0, 2) | ||
167 | + self.horizontalLayout.addLayout(self.verticalLayout) | ||
168 | + self.horizontalLayout_2.addWidget(self.frame) | ||
169 | + self.frame_2 = QtWidgets.QFrame(self.centralwidget) | ||
170 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) | ||
171 | + sizePolicy.setHorizontalStretch(0) | ||
172 | + sizePolicy.setVerticalStretch(0) | ||
173 | + sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth()) | ||
174 | + self.frame_2.setSizePolicy(sizePolicy) | ||
175 | + self.frame_2.setMinimumSize(QtCore.QSize(0, 60)) | ||
176 | + font = QtGui.QFont() | ||
177 | + font.setFamily("宋体") | ||
178 | + font.setPointSize(11) | ||
179 | + self.frame_2.setFont(font) | ||
180 | + self.frame_2.setLayoutDirection(QtCore.Qt.LeftToRight) | ||
181 | + self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) | ||
182 | + self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) | ||
183 | + self.frame_2.setObjectName("frame_2") | ||
184 | + self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.frame_2) | ||
185 | + if self.sys_type == 10: | ||
186 | + self.horizontalLayout_3.setContentsMargins(0, 10, 50, 10) | ||
187 | + self.horizontalLayout_3.setSpacing(50) | ||
188 | + else: | ||
189 | + self.horizontalLayout_3.setContentsMargins(0, 10, 10, 10) | ||
190 | + self.horizontalLayout_3.setSpacing(20) | ||
191 | + self.horizontalLayout_3.setObjectName("horizontalLayout_3") | ||
192 | + self.label_3 = QtWidgets.QLabel(self.frame_2) | ||
193 | + font = QtGui.QFont() | ||
194 | + font.setFamily("宋体") | ||
195 | + font.setPointSize(11) | ||
196 | + self.label_3.setFont(font) | ||
197 | + self.label_3.setText("") | ||
198 | + self.label_3.setObjectName("label_3") | ||
199 | + self.horizontalLayout_3.addWidget(self.label_3) | ||
200 | + self.commandLinkButton_2 = QtWidgets.QCommandLinkButton(self.frame_2) | ||
201 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding) | ||
202 | + sizePolicy.setHorizontalStretch(0) | ||
203 | + sizePolicy.setVerticalStretch(0) | ||
204 | + sizePolicy.setHeightForWidth(self.commandLinkButton_2.sizePolicy().hasHeightForWidth()) | ||
205 | + self.commandLinkButton_2.setSizePolicy(sizePolicy) | ||
206 | + self.commandLinkButton_2.setMinimumSize(QtCore.QSize(80, 40)) | ||
207 | + self.commandLinkButton_2.setMaximumSize(QtCore.QSize(80, 40)) | ||
208 | + font = QtGui.QFont() | ||
209 | + font.setFamily("宋体") | ||
210 | + font.setPointSize(11) | ||
211 | + self.commandLinkButton_2.setFont(font) | ||
212 | + self.commandLinkButton_2.setLayoutDirection(QtCore.Qt.LeftToRight) | ||
213 | + icon1 = QtGui.QIcon() | ||
214 | + icon1.addPixmap(QtGui.QPixmap(":/icon/imgs/login_off.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
215 | + self.commandLinkButton_2.setIcon(icon1) | ||
216 | + self.commandLinkButton_2.setAutoRepeatDelay(30) | ||
217 | + self.commandLinkButton_2.setAutoRepeatInterval(10) | ||
218 | + self.commandLinkButton_2.setObjectName("commandLinkButton_2") | ||
219 | + self.horizontalLayout_3.addWidget(self.commandLinkButton_2) | ||
220 | + self.commandLinkButton = QtWidgets.QCommandLinkButton(self.frame_2) | ||
221 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding) | ||
222 | + sizePolicy.setHorizontalStretch(0) | ||
223 | + sizePolicy.setVerticalStretch(0) | ||
224 | + sizePolicy.setHeightForWidth(self.commandLinkButton.sizePolicy().hasHeightForWidth()) | ||
225 | + self.commandLinkButton.setSizePolicy(sizePolicy) | ||
226 | + self.commandLinkButton.setMinimumSize(QtCore.QSize(80, 40)) | ||
227 | + self.commandLinkButton.setMaximumSize(QtCore.QSize(80, 40)) | ||
228 | + font = QtGui.QFont() | ||
229 | + font.setFamily("宋体") | ||
230 | + font.setPointSize(11) | ||
231 | + self.commandLinkButton.setFont(font) | ||
232 | + self.commandLinkButton.setLayoutDirection(QtCore.Qt.LeftToRight) | ||
233 | + icon2 = QtGui.QIcon() | ||
234 | + icon2.addPixmap(QtGui.QPixmap(":/icon/imgs/login_out.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
235 | + self.commandLinkButton.setIcon(icon2) | ||
236 | + self.commandLinkButton.setAutoRepeatDelay(30) | ||
237 | + self.commandLinkButton.setAutoRepeatInterval(10) | ||
238 | + self.commandLinkButton.setObjectName("commandLinkButton") | ||
239 | + self.horizontalLayout_3.addWidget(self.commandLinkButton) | ||
240 | + self.commandLinkButton.raise_() | ||
241 | + self.commandLinkButton_2.raise_() | ||
242 | + self.label_3.raise_() | ||
243 | + self.horizontalLayout_2.addWidget(self.frame_2) | ||
244 | + self.verticalLayout_2.addLayout(self.horizontalLayout_2) | ||
245 | + self.line = QtWidgets.QFrame(self.centralwidget) | ||
246 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) | ||
247 | + sizePolicy.setHorizontalStretch(0) | ||
248 | + sizePolicy.setVerticalStretch(0) | ||
249 | + sizePolicy.setHeightForWidth(self.line.sizePolicy().hasHeightForWidth()) | ||
250 | + self.line.setSizePolicy(sizePolicy) | ||
251 | + font = QtGui.QFont() | ||
252 | + font.setFamily("宋体") | ||
253 | + font.setPointSize(11) | ||
254 | + self.line.setFont(font) | ||
255 | + self.line.setFrameShape(QtWidgets.QFrame.HLine) | ||
256 | + self.line.setFrameShadow(QtWidgets.QFrame.Sunken) | ||
257 | + self.line.setObjectName("line") | ||
258 | + self.verticalLayout_2.addWidget(self.line) | ||
259 | + self.frame_4 = QtWidgets.QFrame(self.centralwidget) | ||
260 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) | ||
261 | + sizePolicy.setHorizontalStretch(0) | ||
262 | + sizePolicy.setVerticalStretch(0) | ||
263 | + sizePolicy.setHeightForWidth(self.frame_4.sizePolicy().hasHeightForWidth()) | ||
264 | + self.frame_4.setSizePolicy(sizePolicy) | ||
265 | + self.frame_4.setMinimumSize(QtCore.QSize(0, 60)) | ||
266 | + self.frame_4.setMaximumSize(QtCore.QSize(16777215, 60)) | ||
267 | + font = QtGui.QFont() | ||
268 | + font.setFamily("宋体") | ||
269 | + font.setPointSize(11) | ||
270 | + self.frame_4.setFont(font) | ||
271 | + self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel) | ||
272 | + self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised) | ||
273 | + self.frame_4.setObjectName("frame_4") | ||
274 | + self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.frame_4) | ||
275 | + if self.sys_type == 10: | ||
276 | + self.horizontalLayout_5.setContentsMargins(50, 0, 50, 0) | ||
277 | + self.horizontalLayout_5.setSpacing(50) | ||
278 | + else: | ||
279 | + self.horizontalLayout_5.setContentsMargins(10, 0, 10, 0) | ||
280 | + self.horizontalLayout_5.setSpacing(20) | ||
281 | + self.horizontalLayout_5.setObjectName("horizontalLayout_5") | ||
282 | + self.commandLinkButton_3 = QtWidgets.QCommandLinkButton(self.frame_4) | ||
283 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) | ||
284 | + sizePolicy.setHorizontalStretch(0) | ||
285 | + sizePolicy.setVerticalStretch(0) | ||
286 | + sizePolicy.setHeightForWidth(self.commandLinkButton_3.sizePolicy().hasHeightForWidth()) | ||
287 | + self.commandLinkButton_3.setSizePolicy(sizePolicy) | ||
288 | + self.commandLinkButton_3.setMinimumSize(QtCore.QSize(110, 40)) | ||
289 | + self.commandLinkButton_3.setMaximumSize(QtCore.QSize(110, 40)) | ||
290 | + font = QtGui.QFont() | ||
291 | + font.setFamily("宋体") | ||
292 | + font.setPointSize(11) | ||
293 | + self.commandLinkButton_3.setFont(font) | ||
294 | + icon3 = QtGui.QIcon() | ||
295 | + icon3.addPixmap(QtGui.QPixmap(":/icon/imgs/do_task.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
296 | + self.commandLinkButton_3.setIcon(icon3) | ||
297 | + self.commandLinkButton_3.setIconSize(QtCore.QSize(20, 20)) | ||
298 | + self.commandLinkButton_3.setAutoRepeatDelay(30) | ||
299 | + self.commandLinkButton_3.setAutoRepeatInterval(10) | ||
300 | + self.commandLinkButton_3.setObjectName("commandLinkButton_3") | ||
301 | + self.horizontalLayout_5.addWidget(self.commandLinkButton_3) | ||
302 | + self.commandLinkButton_4 = QtWidgets.QCommandLinkButton(self.frame_4) | ||
303 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) | ||
304 | + sizePolicy.setHorizontalStretch(0) | ||
305 | + sizePolicy.setVerticalStretch(0) | ||
306 | + sizePolicy.setHeightForWidth(self.commandLinkButton_4.sizePolicy().hasHeightForWidth()) | ||
307 | + self.commandLinkButton_4.setSizePolicy(sizePolicy) | ||
308 | + self.commandLinkButton_4.setMinimumSize(QtCore.QSize(110, 40)) | ||
309 | + self.commandLinkButton_4.setMaximumSize(QtCore.QSize(110, 40)) | ||
310 | + font = QtGui.QFont() | ||
311 | + font.setFamily("宋体") | ||
312 | + font.setPointSize(11) | ||
313 | + self.commandLinkButton_4.setFont(font) | ||
314 | + icon4 = QtGui.QIcon() | ||
315 | + icon4.addPixmap(QtGui.QPixmap(":/icon/imgs/doed_task.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
316 | + self.commandLinkButton_4.setIcon(icon4) | ||
317 | + self.commandLinkButton_4.setIconSize(QtCore.QSize(22, 20)) | ||
318 | + self.commandLinkButton_4.setAutoRepeatDelay(30) | ||
319 | + self.commandLinkButton_4.setAutoRepeatInterval(10) | ||
320 | + self.commandLinkButton_4.setObjectName("commandLinkButton_4") | ||
321 | + self.horizontalLayout_5.addWidget(self.commandLinkButton_4) | ||
322 | + self.label_6 = QtWidgets.QLabel(self.frame_4) | ||
323 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) | ||
324 | + sizePolicy.setHorizontalStretch(0) | ||
325 | + sizePolicy.setVerticalStretch(0) | ||
326 | + sizePolicy.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth()) | ||
327 | + self.label_6.setSizePolicy(sizePolicy) | ||
328 | + self.label_6.setMinimumSize(QtCore.QSize(0, 40)) | ||
329 | + self.label_6.setMaximumSize(QtCore.QSize(16777215, 40)) | ||
330 | + font = QtGui.QFont() | ||
331 | + font.setFamily("宋体") | ||
332 | + font.setPointSize(14) | ||
333 | + font.setBold(True) | ||
334 | + font.setWeight(75) | ||
335 | + self.label_6.setFont(font) | ||
336 | + self.label_6.setStyleSheet("color: rgb(85, 170, 0);") | ||
337 | + self.label_6.setAlignment(QtCore.Qt.AlignCenter) | ||
338 | + self.label_6.setObjectName("label_6") | ||
339 | + self.horizontalLayout_5.addWidget(self.label_6) | ||
340 | + self.commandLinkButton_5 = QtWidgets.QCommandLinkButton(self.frame_4) | ||
341 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) | ||
342 | + sizePolicy.setHorizontalStretch(0) | ||
343 | + sizePolicy.setVerticalStretch(0) | ||
344 | + sizePolicy.setHeightForWidth(self.commandLinkButton_5.sizePolicy().hasHeightForWidth()) | ||
345 | + self.commandLinkButton_5.setSizePolicy(sizePolicy) | ||
346 | + self.commandLinkButton_5.setMinimumSize(QtCore.QSize(110, 40)) | ||
347 | + self.commandLinkButton_5.setMaximumSize(QtCore.QSize(110, 40)) | ||
348 | + font = QtGui.QFont() | ||
349 | + font.setFamily("宋体") | ||
350 | + font.setPointSize(11) | ||
351 | + self.commandLinkButton_5.setFont(font) | ||
352 | + icon5 = QtGui.QIcon() | ||
353 | + icon5.addPixmap(QtGui.QPixmap(":/icon/imgs/start.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
354 | + self.commandLinkButton_5.setIcon(icon5) | ||
355 | + self.commandLinkButton_5.setAutoRepeatDelay(30) | ||
356 | + self.commandLinkButton_5.setAutoRepeatInterval(10) | ||
357 | + self.commandLinkButton_5.setObjectName("commandLinkButton_5") | ||
358 | + self.horizontalLayout_5.addWidget(self.commandLinkButton_5) | ||
359 | + self.verticalLayout_2.addWidget(self.frame_4) | ||
360 | + self.tableWidget = QtWidgets.QTableWidget(self.centralwidget) | ||
361 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) | ||
362 | + sizePolicy.setHorizontalStretch(0) | ||
363 | + sizePolicy.setVerticalStretch(0) | ||
364 | + sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth()) | ||
365 | + self.tableWidget.setSizePolicy(sizePolicy) | ||
366 | + font = QtGui.QFont() | ||
367 | + font.setFamily("微软雅黑") | ||
368 | + font.setPointSize(11) | ||
369 | + self.tableWidget.setFont(font) | ||
370 | + self.tableWidget.setObjectName("tableWidget") | ||
371 | + self.tableWidget.setColumnCount(0) | ||
372 | + self.tableWidget.setRowCount(0) | ||
373 | + self.verticalLayout_2.addWidget(self.tableWidget) | ||
374 | + self.frame_3 = QtWidgets.QFrame(self.centralwidget) | ||
375 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) | ||
376 | + sizePolicy.setHorizontalStretch(0) | ||
377 | + sizePolicy.setVerticalStretch(0) | ||
378 | + sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth()) | ||
379 | + self.frame_3.setSizePolicy(sizePolicy) | ||
380 | + self.frame_3.setMinimumSize(QtCore.QSize(0, 35)) | ||
381 | + self.frame_3.setMaximumSize(QtCore.QSize(16777215, 35)) | ||
382 | + font = QtGui.QFont() | ||
383 | + font.setFamily("宋体") | ||
384 | + font.setPointSize(11) | ||
385 | + self.frame_3.setFont(font) | ||
386 | + self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) | ||
387 | + self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised) | ||
388 | + self.frame_3.setObjectName("frame_3") | ||
389 | + self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.frame_3) | ||
390 | + self.horizontalLayout_4.setContentsMargins(10, 0, 0, 0) | ||
391 | + self.horizontalLayout_4.setSpacing(2) | ||
392 | + self.horizontalLayout_4.setObjectName("horizontalLayout_4") | ||
393 | + self.label_7 = QtWidgets.QLabel(self.frame_3) | ||
394 | + font = QtGui.QFont() | ||
395 | + font.setFamily("宋体") | ||
396 | + font.setPointSize(10) | ||
397 | + font.setBold(True) | ||
398 | + font.setWeight(75) | ||
399 | + self.label_7.setFont(font) | ||
400 | + self.label_7.setObjectName("label_7") | ||
401 | + self.horizontalLayout_4.addWidget(self.label_7) | ||
402 | + self.label_4 = QtWidgets.QLabel(self.frame_3) | ||
403 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) | ||
404 | + sizePolicy.setHorizontalStretch(0) | ||
405 | + sizePolicy.setVerticalStretch(0) | ||
406 | + sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth()) | ||
407 | + self.label_4.setSizePolicy(sizePolicy) | ||
408 | + self.label_4.setMinimumSize(QtCore.QSize(0, 0)) | ||
409 | + self.label_4.setMaximumSize(QtCore.QSize(16777215, 16777215)) | ||
410 | + font = QtGui.QFont() | ||
411 | + font.setFamily("宋体") | ||
412 | + font.setPointSize(10) | ||
413 | + font.setBold(False) | ||
414 | + font.setWeight(50) | ||
415 | + self.label_4.setFont(font) | ||
416 | + self.label_4.setStyleSheet("") | ||
417 | + self.label_4.setText("") | ||
418 | + self.label_4.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) | ||
419 | + self.label_4.setObjectName("label_4") | ||
420 | + self.horizontalLayout_4.addWidget(self.label_4) | ||
421 | + self.label_8 = QtWidgets.QLabel(self.frame_3) | ||
422 | + font = QtGui.QFont() | ||
423 | + font.setFamily("宋体") | ||
424 | + font.setPointSize(10) | ||
425 | + font.setBold(True) | ||
426 | + font.setWeight(75) | ||
427 | + self.label_8.setFont(font) | ||
428 | + self.label_8.setObjectName("label_8") | ||
429 | + self.horizontalLayout_4.addWidget(self.label_8) | ||
430 | + self.label_5 = QtWidgets.QLabel(self.frame_3) | ||
431 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) | ||
432 | + sizePolicy.setHorizontalStretch(0) | ||
433 | + sizePolicy.setVerticalStretch(0) | ||
434 | + sizePolicy.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth()) | ||
435 | + self.label_5.setSizePolicy(sizePolicy) | ||
436 | + self.label_5.setMinimumSize(QtCore.QSize(0, 0)) | ||
437 | + self.label_5.setMaximumSize(QtCore.QSize(16777215, 16777215)) | ||
438 | + font = QtGui.QFont() | ||
439 | + font.setFamily("宋体") | ||
440 | + font.setPointSize(10) | ||
441 | + self.label_5.setFont(font) | ||
442 | + self.label_5.setStyleSheet("") | ||
443 | + self.label_5.setObjectName("label_5") | ||
444 | + self.horizontalLayout_4.addWidget(self.label_5) | ||
445 | + self.label_9 = QtWidgets.QLabel(self.frame_3) | ||
446 | + font = QtGui.QFont() | ||
447 | + font.setFamily("宋体") | ||
448 | + font.setPointSize(10) | ||
449 | + font.setBold(True) | ||
450 | + font.setWeight(75) | ||
451 | + self.label_9.setFont(font) | ||
452 | + self.label_9.setObjectName("label_9") | ||
453 | + self.horizontalLayout_4.addWidget(self.label_9) | ||
454 | + self.label_10 = QtWidgets.QLabel(self.frame_3) | ||
455 | + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding) | ||
456 | + sizePolicy.setHorizontalStretch(0) | ||
457 | + sizePolicy.setVerticalStretch(0) | ||
458 | + sizePolicy.setHeightForWidth(self.label_10.sizePolicy().hasHeightForWidth()) | ||
459 | + self.label_10.setSizePolicy(sizePolicy) | ||
460 | + self.label_10.setMinimumSize(QtCore.QSize(60, 0)) | ||
461 | + self.label_10.setMaximumSize(QtCore.QSize(60, 16777215)) | ||
462 | + font = QtGui.QFont() | ||
463 | + font.setFamily("宋体") | ||
464 | + font.setPointSize(10) | ||
465 | + self.label_10.setFont(font) | ||
466 | + self.label_10.setText("") | ||
467 | + self.label_10.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) | ||
468 | + self.label_10.setObjectName("label_10") | ||
469 | + self.horizontalLayout_4.addWidget(self.label_10) | ||
470 | + self.horizontalLayout_4.setStretch(1, 2) | ||
471 | + self.horizontalLayout_4.setStretch(3, 1) | ||
472 | + self.verticalLayout_2.addWidget(self.frame_3) | ||
473 | + self.MainWindow.setCentralWidget(self.centralwidget) | ||
474 | + | ||
475 | + self.retranslateUi(self.MainWindow) | ||
476 | + self.cur_btn = self.commandLinkButton_3 | ||
477 | + self.__init_click() | ||
478 | + | ||
479 | + self.set_content() | ||
480 | + DBClass().execute('DELETE FROM task where status != ?', (STATUS_SUCCESS,)) | ||
481 | + q_do_task.put(True) | ||
482 | + | ||
483 | + QtCore.QMetaObject.connectSlotsByName(self.MainWindow) | ||
484 | + | ||
485 | + def retranslateUi(self, MainWindow): | ||
486 | + _translate = QtCore.QCoreApplication.translate | ||
487 | + MainWindow.setWindowTitle(_translate("MainWindow", "智能数据助手 " + VERSION)) | ||
488 | + # self.label.setText(_translate("MainWindow", "北京小爱智能科技有限公司")) | ||
489 | + # self.label.setText(_translate("MainWindow", "北京冠华英才(测试)智能数据助手")) | ||
490 | + self.label.setText(_translate("MainWindow", "深圳工源智能数据助手")) | ||
491 | + self.label_2.setText(_translate("MainWindow", "Social Tax Intelligent Data Assistant " + VERSION)) | ||
492 | + self.commandLinkButton_2.setText(_translate("MainWindow", "注销")) | ||
493 | + self.commandLinkButton.setText(_translate("MainWindow", "退出")) | ||
494 | + self.commandLinkButton_3.setText(_translate("MainWindow", "待办任务")) | ||
495 | + self.commandLinkButton_4.setText(_translate("MainWindow", "已办任务")) | ||
496 | + self.label_6.setText(_translate("MainWindow", "空闲中...")) | ||
497 | + self.commandLinkButton_5.setText(_translate("MainWindow", "立即办理")) | ||
498 | + self.label_7.setText(_translate("MainWindow", "公司名称:")) | ||
499 | + self.label_8.setText(_translate("MainWindow", "用户姓名:")) | ||
500 | + self.label_9.setText(_translate("MainWindow", "平台类型:")) | ||
501 | + | ||
502 | + def __init_click(self): | ||
503 | + self.commandLinkButton.clicked.connect(self.login_out) | ||
504 | + | ||
505 | + def login_out(self): | ||
506 | + """退出启动窗口事件""" | ||
507 | + result = QMessageBox.question(self.MainWindow, '提示', '确定要退出智能数据助手吗?', QMessageBox.Yes | QMessageBox.No) | ||
508 | + if result == 16384: | ||
509 | + self.MainWindow.close() | ||
510 | + return True | ||
511 | + return False | ||
512 | + | ||
513 | + def login_off(self, filename): | ||
514 | + """退出启动窗口事件""" | ||
515 | + result = QMessageBox.question(self.MainWindow, '提示', '确定要注销当前账号吗?', QMessageBox.Yes | QMessageBox.No) | ||
516 | + if result == 16384: | ||
517 | + DBClass().execute('DELETE FROM account') | ||
518 | + os.system('start ' + filename) | ||
519 | + self.MainWindow.close() | ||
520 | + | ||
521 | + def set_content(self): | ||
522 | + """设置待办任务和已办任务标题信息""" | ||
523 | + column_name = ['文件名称', '业务类型', '平台类型', '办理时间', '任务状态', '备注信息'] | ||
524 | + if self.cur_btn == self.commandLinkButton_3: | ||
525 | + self.commandLinkButton_3.setEnabled(False) | ||
526 | + self.commandLinkButton_4.setEnabled(True) | ||
527 | + column_name = ['文件名称', '业务类型', '平台类型', '办理时间', '任务状态', '备注信息'] | ||
528 | + elif self.cur_btn == self.commandLinkButton_4: | ||
529 | + self.commandLinkButton_3.setEnabled(True) | ||
530 | + self.commandLinkButton_4.setEnabled(False) | ||
531 | + column_name = ['文件名称', '业务类型', '平台类型', '完成时间', '任务状态', '备注信息'] | ||
532 | + | ||
533 | + self.tableWidget.setColumnCount(6) | ||
534 | + self.tableWidget.horizontalHeader().setDefaultSectionSize(265) | ||
535 | + self.tableWidget.verticalHeader().setDefaultSectionSize(35) | ||
536 | + self.tableWidget.setColumnWidth(1, 90) | ||
537 | + self.tableWidget.setColumnWidth(2, 90) | ||
538 | + self.tableWidget.setColumnWidth(3, 150) | ||
539 | + self.tableWidget.setColumnWidth(4, 90) | ||
540 | + self.tableWidget.setHorizontalHeaderLabels(column_name) | ||
541 | + | ||
542 | + def update_dotask(self, data): | ||
543 | + """更新待办理任务列表""" | ||
544 | + _data = json.loads(data) | ||
545 | + if len(_data) == 0: | ||
546 | + self.tableWidget.setRowCount(0) | ||
547 | + else: | ||
548 | + flag = 0 | ||
549 | + if _data['status'] == '正在办理': | ||
550 | + flag = 1 | ||
551 | + elif _data['status'] == '办理失败': | ||
552 | + flag = 2 | ||
553 | + elif _data['status'] == '办理成功': | ||
554 | + flag = 3 | ||
555 | + | ||
556 | + self.tableWidget.setRowCount(_data['cnt']) | ||
557 | + self.tableWidget.setItem(_data['row'], 0, self.__create_item(_data['filename'], flag=flag)) | ||
558 | + self.tableWidget.setItem(_data['row'], 1, self.__create_item(_data['bus_type'], flag=flag)) | ||
559 | + self.tableWidget.setItem(_data['row'], 2, self.__create_item(_data['plat_type'], flag=flag)) | ||
560 | + self.tableWidget.setItem(_data['row'], 3, self.__create_item(_data['task_time'], flag=flag)) | ||
561 | + self.tableWidget.setItem(_data['row'], 4, self.__create_item(_data['status'], flag=flag)) | ||
562 | + self.tableWidget.setItem(_data['row'], 5, self.__create_item(_data['comment'], flag=flag)) | ||
563 | + | ||
564 | + def update_doedtask(self, data): | ||
565 | + """更新已办理任务列表""" | ||
566 | + _data = json.loads(data) | ||
567 | + if len(_data) == 0: | ||
568 | + self.tableWidget.setRowCount(0) | ||
569 | + else: | ||
570 | + flag = 0 | ||
571 | + if _data['status'] == '正在办理': | ||
572 | + flag = 1 | ||
573 | + elif _data['status'] == '办理失败': | ||
574 | + flag = 2 | ||
575 | + elif _data['status'] == '办理成功': | ||
576 | + flag = 3 | ||
577 | + | ||
578 | + self.tableWidget.setRowCount(_data['cnt']) | ||
579 | + self.tableWidget.setItem(_data['row'], 0, self.__create_item(_data['filename'], flag=flag)) | ||
580 | + self.tableWidget.setItem(_data['row'], 1, self.__create_item(_data['bus_type'], flag=flag)) | ||
581 | + self.tableWidget.setItem(_data['row'], 2, self.__create_item(_data['plat_type'], flag=flag)) | ||
582 | + self.tableWidget.setItem(_data['row'], 3, self.__create_item(_data['task_time'], flag=flag)) | ||
583 | + self.tableWidget.setItem(_data['row'], 4, self.__create_item(_data['status'], flag=flag)) | ||
584 | + self.tableWidget.setItem(_data['row'], 5, self.__create_item(_data['comment'], flag=flag)) | ||
585 | + | ||
586 | + def __create_item(self, content, flag=0): | ||
587 | + """创建列表item对象""" | ||
588 | + item = QTableWidgetItem(content) | ||
589 | + font = QtGui.QFont("微软雅黑", 10, QtGui.QFont.Normal) | ||
590 | + item.setFont(font) | ||
591 | + item.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter) | ||
592 | + if flag == 1: | ||
593 | + item.setForeground(QBrush(QColor(255, 170, 0))) | ||
594 | + elif flag == 2: | ||
595 | + item.setForeground(QBrush(QColor(255, 0, 0))) | ||
596 | + elif flag == 3: | ||
597 | + item.setForeground(QBrush(QColor(0, 0, 255))) | ||
598 | + else: | ||
599 | + item.setForeground(QBrush(QColor(0, 0, 0))) | ||
600 | + item.setFlags(QtCore.Qt.ItemIsEnabled) | ||
601 | + return item | ||
602 | + | ||
603 | + def get_do_task(self): | ||
604 | + """获取待办任务列表""" | ||
605 | + self.cur_btn = self.commandLinkButton_3 | ||
606 | + self.set_content() | ||
607 | + q_do_task.put(True) | ||
608 | + | ||
609 | + def get_doed_task(self): | ||
610 | + """获取待办任务列表""" | ||
611 | + self.cur_btn = self.commandLinkButton_4 | ||
612 | + self.set_content() | ||
613 | + q_doed_task.put(True) | ||
614 | + | ||
615 | + def start_task(self, tenant_id, tenant_type): | ||
616 | + """立即办理任务""" | ||
617 | + Thread(target=self.check_work_floder, daemon=True).start() | ||
618 | + result = q_floder.get() | ||
619 | + if result == -1: | ||
620 | + QMessageBox.warning(self.MainWindow, '消息', "查询并获取用户配置信息失败!") | ||
621 | + elif result == 0: | ||
622 | + QMessageBox.warning(self.MainWindow, '消息', "您设置的工作目录不存在,请注销后重新设定!") | ||
623 | + elif result == 1: | ||
624 | + QMessageBox.warning(self.MainWindow, '消息', "您的工作目录没有检测到可被办理的任务!") | ||
625 | + elif result == 2: | ||
626 | + Thread(target=self.get_file_tasks, args=(tenant_id, tenant_type), daemon=True).start() | ||
627 | + Thread(target=self.update_task, daemon=True).start() | ||
628 | + else: | ||
629 | + QMessageBox.warning(self.MainWindow, '消息', "网络或服务器异常,请稍后再试!") | ||
630 | + | ||
631 | + def check_work_floder(self): | ||
632 | + """检查工作目录是否存在有效""" | ||
633 | + try: | ||
634 | + self.set_enable() | ||
635 | + result = DBClass().execute('SELECT ac_floder FROM account') | ||
636 | + if not result or result == DB_STATUS_FAIL: | ||
637 | + logger.error("查询用户设置的工作目录失败...") | ||
638 | + self.set_enable(flag=1) | ||
639 | + q_floder.put(-1) | ||
640 | + else: | ||
641 | + work_path = result[0][0] | ||
642 | + if not os.path.exists(work_path): | ||
643 | + self.set_enable(flag=1) | ||
644 | + q_floder.put(0) | ||
645 | + else: | ||
646 | + logger.info("工作目录:" + work_path) | ||
647 | + self.work_path = work_path | ||
648 | + files = os.listdir(self.work_path) | ||
649 | + sure_lst, err_lst = check_is_file(self.work_path, files) | ||
650 | + if not sure_lst: | ||
651 | + self.set_enable(flag=1) | ||
652 | + q_floder.put(1) | ||
653 | + else: | ||
654 | + self.sure_lst = sure_lst | ||
655 | + self.err_lst = err_lst | ||
656 | + q_floder.put(2) | ||
657 | + except Exception as e: | ||
658 | + logger.error(str(e)) | ||
659 | + self.set_enable(flag=1) | ||
660 | + q_floder.put(-2) | ||
661 | + | ||
662 | + def get_file_tasks(self, tenant_id, tenant_type): | ||
663 | + """开始办理文件任务""" | ||
664 | + try: | ||
665 | + DBClass().execute('DELETE FROM task where status != ?', (STATUS_SUCCESS,)) | ||
666 | + file_list = clean_up_file(tenant_type, self.sure_lst, self.err_lst) | ||
667 | + if file_list: | ||
668 | + ins_list, salary_list = order_task(file_list) | ||
669 | + if tenant_type == "0": | ||
670 | + if ins_list: | ||
671 | + for item in ins_list: | ||
672 | + t_err = Thread(target=update_task, args=(item[0], STATUS_FAIL, 'HRO平台不支持社保业务')) | ||
673 | + t_err.start() | ||
674 | + t_err.join() | ||
675 | + if salary_list: | ||
676 | + args = self.work_path, salary_list, tenant_id, tenant_type | ||
677 | + t_salary = Thread(target=batch_update_files, args=args) | ||
678 | + t_salary.start() | ||
679 | + t_salary.join() | ||
680 | + elif tenant_type == "1": | ||
681 | + if ins_list: | ||
682 | + args = self.work_path, ins_list, tenant_id, tenant_type | ||
683 | + t_ins = Thread(target=batch_update_files, args=args) | ||
684 | + t_ins.start() | ||
685 | + t_ins.join() | ||
686 | + if salary_list: | ||
687 | + time.sleep(2) | ||
688 | + args = self.work_path, salary_list, tenant_id, tenant_type | ||
689 | + t_salary = Thread(target=batch_update_files, args=args) | ||
690 | + t_salary.start() | ||
691 | + t_salary.join() | ||
692 | + else: | ||
693 | + if salary_list: | ||
694 | + args = self.work_path, salary_list, tenant_id, tenant_type | ||
695 | + t_salary = Thread(target=batch_update_files, args=args) | ||
696 | + t_salary.start() | ||
697 | + t_salary.join() | ||
698 | + self.set_enable(flag=1) | ||
699 | + except Exception as e: | ||
700 | + logger.error(str(e)) | ||
701 | + self.set_enable(flag=1) | ||
702 | + | ||
703 | + def update_task(self): | ||
704 | + """动态更新待办和已办任务列表""" | ||
705 | + while True: | ||
706 | + if self.cur_btn == self.commandLinkButton_3: | ||
707 | + q_do_task.put(True) | ||
708 | + elif self.cur_btn == self.commandLinkButton_4: | ||
709 | + q_doed_task.put(True) | ||
710 | + if not self.is_refresh: | ||
711 | + self.commandLinkButton.setEnabled(True) | ||
712 | + self.commandLinkButton_2.setEnabled(True) | ||
713 | + self.commandLinkButton_5.setEnabled(True) | ||
714 | + break | ||
715 | + time.sleep(1) | ||
716 | + | ||
717 | + def set_enable(self, flag=0): | ||
718 | + if flag == 0: | ||
719 | + self.commandLinkButton.setEnabled(False) | ||
720 | + self.commandLinkButton_2.setEnabled(False) | ||
721 | + self.commandLinkButton_5.setEnabled(False) | ||
722 | + self.is_refresh = True | ||
723 | + self.label_6.setStyleSheet("color: rgb(255, 0, 0);") | ||
724 | + self.label_6.setText(self._translate("MainWindow", "办理中...")) | ||
725 | + else: | ||
726 | + self.label_6.setStyleSheet("color: rgb(0, 0, 255);") | ||
727 | + self.label_6.setText(self._translate("MainWindow", "已结束...")) | ||
728 | + time.sleep(3) | ||
729 | + self.label_6.setStyleSheet("color: rgb(85, 170, 0);") | ||
730 | + self.label_6.setText(self._translate("MainWindow", "空闲中...")) | ||
731 | + self.commandLinkButton.setEnabled(True) | ||
732 | + self.commandLinkButton_2.setEnabled(True) | ||
733 | + self.commandLinkButton_5.setEnabled(True) | ||
734 | + self.is_refresh = False | ||
735 | + | ||
736 | + def mainform_show(self): | ||
737 | + self.MainWindow.show() | ||
738 | + if self.MainWindow.isVisible(): | ||
739 | + userinfo = get_userinfo()[0] | ||
740 | + if userinfo: | ||
741 | + company = userinfo[3] | ||
742 | + username = userinfo[4] | ||
743 | + self.label_4.setText(self._translate('MainWindow', company)) | ||
744 | + self.label_5.setText(self._translate('MainWindow', username)) | ||
745 | + self.label_10.setText(self._translate('MainWindow', userinfo[5])) | ||
746 | + | ||
747 | + def change_title_color(self): | ||
748 | + delay = 2 | ||
749 | + while True: | ||
750 | + self.label.setStyleSheet("color: rgb(85, 0, 255);") | ||
751 | + time.sleep(delay) | ||
752 | + self.label.setStyleSheet("color: rgb(255, 0, 0);") | ||
753 | + time.sleep(delay) | ||
754 | + self.label.setStyleSheet("color: rgb(85, 170, 0);") | ||
755 | + time.sleep(delay) |
taxbot/forms/msgform.py
0 → 100644
1 | +# -*- coding: utf-8 -*- | ||
2 | +from PyQt5.QtCore import Qt | ||
3 | +from PyQt5 import QtCore, QtGui, QtWidgets | ||
4 | +from PyQt5.QtWidgets import QMainWindow | ||
5 | +from qrc import icon | ||
6 | + | ||
7 | + | ||
8 | +class Ui_MsgWindow(object): | ||
9 | + def __init__(self): | ||
10 | + self.MsgWindow = QMainWindow() | ||
11 | + self.font = QtGui.QFont() | ||
12 | + self.msg = '智能数据助手启动成功!' | ||
13 | + self.font.setFamily("微软雅黑") | ||
14 | + self.font.setPointSize(10) | ||
15 | + self.centralwidget = QtWidgets.QWidget(self.MsgWindow) | ||
16 | + self._translate = QtCore.QCoreApplication.translate | ||
17 | + | ||
18 | + def __init_window_ui(self): | ||
19 | + """初始化窗口框架""" | ||
20 | + self.MsgWindow.setObjectName("MsgWindow") | ||
21 | + self.MsgWindow.setFixedSize(230, 120) | ||
22 | + self.MsgWindow.setWindowFlags(Qt.WindowStaysOnTopHint) | ||
23 | + self.MsgWindow.setWindowFlags(Qt.WindowMinimizeButtonHint) | ||
24 | + # self.LoginWindow.setWindowFlags(Qt.FramelessWindowHint) | ||
25 | + icon = QtGui.QIcon() | ||
26 | + icon.addPixmap(QtGui.QPixmap(":/icon/imgs/logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) | ||
27 | + self.MsgWindow.setWindowIcon(icon) | ||
28 | + self.MsgWindow.setWindowTitle(self._translate("MsgWindow", "消息")) | ||
29 | + | ||
30 | + self.label = QtWidgets.QLabel(self.centralwidget) | ||
31 | + self.label.setGeometry(QtCore.QRect(10, 20, 211, 30)) | ||
32 | + self.label.setFont(self.font) | ||
33 | + self.label.setAlignment(QtCore.Qt.AlignCenter) | ||
34 | + self.label.setText(self._translate("MsgWindow", self.msg)) | ||
35 | + self.pushButton = QtWidgets.QPushButton(self.centralwidget) | ||
36 | + self.pushButton.setGeometry(QtCore.QRect(80, 70, 70, 26)) | ||
37 | + self.pushButton.setText(self._translate("MsgWindow", "确定")) | ||
38 | + self.MsgWindow.setCentralWidget(self.centralwidget) | ||
39 | + QtCore.QMetaObject.connectSlotsByName(self.MsgWindow) | ||
40 | + | ||
41 | + def setupUi(self, msg): | ||
42 | + if msg != '': | ||
43 | + self.msg = msg | ||
44 | + self.__init_window_ui() | ||
45 | + self.__init_click() | ||
46 | + | ||
47 | + def __init_click(self): | ||
48 | + self.pushButton.clicked.connect(self.__sure) | ||
49 | + | ||
50 | + def __sure(self): | ||
51 | + """退出启动窗口事件""" | ||
52 | + self.MsgWindow.close() |
taxbot/imgs/do_task.png
0 → 100644
16.0 KB
taxbot/imgs/doed_task.png
0 → 100644
15.5 KB
taxbot/imgs/login_off.png
0 → 100644
3.5 KB
taxbot/imgs/login_out.png
0 → 100644
8.5 KB
taxbot/imgs/logo.png
0 → 100644
10.0 KB
taxbot/imgs/start.png
0 → 100644
10.0 KB
taxbot/model/__init__.py
0 → 100644
taxbot/model/task.py
0 → 100644
taxbot/qrc/__init__.py
0 → 100644
taxbot/qrc/icon.py
0 → 100644
此 diff 太大无法显示。
taxbot/qrc/icon.qrc
0 → 100644
请
注册
或
登录
后发表评论