license_info_distribution.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. // 显示分发模态框的函数
  2. function showDistributeModal(item) {
  3. const modal = document.getElementById('DistributeModal');
  4. // 显示模态框
  5. modal.style.display = 'flex';
  6. let usersInfo;
  7. // 获取用户信息并填充第一个用户输入框
  8. fetch('http://127.0.0.1:8080/api/admin/distributeLicenseByUserInfo', {
  9. method: 'GET',
  10. headers: {
  11. 'Authorization': `Bearer ${authToken}`, // 确保autoToken是您获取的用户授权令牌
  12. 'Content-Type': 'application/json'
  13. }
  14. })
  15. .then(response => {
  16. if (!response.ok) {
  17. throw new Error('Network response was not ok');
  18. }
  19. return response.json();
  20. })
  21. .then(data => {
  22. usersInfo = data.data; // 假设 data 是返回的用户信息数组或对象
  23. console.log('用户信息:', usersInfo); // 打印用户信息
  24. // 调用处理上半部分(邮箱输入框)的函数
  25. handleEmailSection(item,usersInfo);
  26. // 调用处理下半部分(用户输入框)的函数
  27. handleUserSection(item, usersInfo);
  28. })
  29. .catch(error => {
  30. console.error('获取用户信息失败:', error);
  31. });
  32. // 绑定关闭事件
  33. const closeModalBtn = document.querySelector('.DistributeModal-close');
  34. closeModalBtn.addEventListener('click', closeDistributeModal);
  35. // 点击模态框外部关闭
  36. window.addEventListener('click', (event) => {
  37. if (event.target === modal) {
  38. closeDistributeModal();
  39. }
  40. });
  41. }
  42. function handleEmailSection(item,usersInfo) {
  43. console.log('调用邮箱处理');
  44. console.log('handleEmailSection 用户信息:', usersInfo); // 打印用户信息
  45. const emailInputs = document.getElementById('DistributeModal-email-inputs');
  46. emailInputs.innerHTML = ''; // 清空之前添加的邮箱输入框
  47. // 设置复选框标签内容
  48. const salesEmailLabel = document.getElementById('salesEmailCheckbox').parentElement;
  49. salesEmailLabel.innerHTML = `
  50. <input type="checkbox" id="salesEmailCheckbox" class="DistributeModal-checkbox">
  51. <span class="DistributeModal-checkbox-custom"></span>
  52. 销售邮箱 (${item.SalesPerson}: ${item.SalesEmail})
  53. `;
  54. const supportEmailLabel = document.getElementById('supportEmailCheckbox').parentElement;
  55. supportEmailLabel.innerHTML = `
  56. <input type="checkbox" id="supportEmailCheckbox" class="DistributeModal-checkbox">
  57. <span class="DistributeModal-checkbox-custom"></span>
  58. 运维邮箱 (${item.SupportPerson}: ${item.SupportEmail})
  59. `;
  60. // 防止重复绑定事件,先移除任何现有的点击事件监听器
  61. const addEmailBtn = document.getElementById('DistributeModal-add-email-btn');
  62. addEmailBtn.replaceWith(addEmailBtn.cloneNode(true)); // 通过克隆移除所有之前绑定的事件
  63. const newAddEmailBtn = document.getElementById('DistributeModal-add-email-btn');
  64. // 绑定一次点击事件,动态添加邮箱输入框
  65. newAddEmailBtn.addEventListener('click', () => {
  66. const emailWrapper = document.createElement('div');
  67. emailWrapper.className = 'DistributeModal-email-input-wrapper';
  68. const newEmailInput = document.createElement('input');
  69. newEmailInput.type = 'email';
  70. newEmailInput.placeholder = '输入分发邮箱';
  71. newEmailInput.className = 'DistributeModal-email-input';
  72. // 创建删除按钮
  73. const removeEmailBtn = document.createElement('button');
  74. removeEmailBtn.className = 'DistributeModal-remove-email-btn';
  75. removeEmailBtn.innerHTML = '&times;'; // × 符号
  76. removeEmailBtn.addEventListener('click', () => {
  77. emailWrapper.remove(); // 删除邮箱输入框
  78. });
  79. // 将输入框和删除按钮加入到 emailWrapper 中
  80. emailWrapper.appendChild(newEmailInput);
  81. emailWrapper.appendChild(removeEmailBtn);
  82. // 将 emailWrapper 加入到 emailInputs 容器中
  83. emailInputs.appendChild(emailWrapper);
  84. });
  85. // 内部函数:检查是否存在重复项
  86. function findDuplicates(arr) {
  87. const seen = new Set();
  88. const duplicates = [];
  89. arr.forEach((email) => {
  90. if (seen.has(email)) {
  91. duplicates.push(email);
  92. } else {
  93. seen.add(email);
  94. }
  95. });
  96. return duplicates;
  97. }
  98. // 点击上半部分的确认按钮
  99. const emailConfirmBtn = document.getElementById('DistributeModal-email-confirm-btn');
  100. emailConfirmBtn.addEventListener('click', () => {
  101. // 收集邮箱信息
  102. let emails = Array.from(document.querySelectorAll('.DistributeModal-email-input'))
  103. .map(input => input.value.trim());
  104. // 检查是否勾选销售邮箱或运维邮箱
  105. const isSalesEmailChecked = document.getElementById('salesEmailCheckbox').checked;
  106. const isSupportEmailChecked = document.getElementById('supportEmailCheckbox').checked;
  107. if (isSalesEmailChecked) {
  108. emails.push(item.SalesEmail); // 如果勾选了销售邮箱,添加到邮箱列表
  109. }
  110. if (isSupportEmailChecked) {
  111. emails.push(item.SupportEmail); // 如果勾选了运维邮箱,添加到邮箱列表
  112. }
  113. // 检查是否存在重复的邮箱
  114. const duplicateEmails = findDuplicates(emails);
  115. if (duplicateEmails.length > 0) {
  116. // 如果有重复的邮箱,弹出提示
  117. alert(`以下邮箱重复:\n${duplicateEmails.join('\n')}`);
  118. } else {
  119. // 没有重复的邮箱,弹出确认发送提示
  120. if (confirm("确认发送这些邮件吗?")) {
  121. // 执行邮箱分发逻辑
  122. // distributeLicense(item, emails, []);
  123. distributeEmails(item, emails, usersInfo);
  124. closeDistributeModal(); // 关闭模态框
  125. }
  126. }
  127. });
  128. }
  129. function handleUserSection(item, usersInfo) {
  130. console.log('handleUserSection 用户信息:', usersInfo); // 打印用户信息
  131. const userInputs = document.getElementById('DistributeModal-user-inputs');
  132. userInputs.innerHTML = ''; // 清空之前添加的用户选择框
  133. // 过滤掉 admin 账户
  134. const filteredUsersInfo = usersInfo.filter(user => user.Username !== 'admin');
  135. // 用于存储已经选择的用户
  136. let selectedUsersSet = new Set();
  137. // 绑定新增下拉框按钮
  138. const addSelectBtn = document.getElementById('distributeUser-add-select-btn');
  139. addSelectBtn.replaceWith(addSelectBtn.cloneNode(true)); // 防止重复绑定
  140. const newAddSelectBtn = document.getElementById('distributeUser-add-select-btn');
  141. // 函数:更新所有下拉框中的可选项
  142. const updateSelectOptions = () => {
  143. Array.from(document.querySelectorAll('.distributeUser-select')).forEach(select => {
  144. const currentValue = select.value; // 当前选中的值
  145. select.innerHTML = ''; // 清空选项
  146. // 添加默认的空选项(必须手动选择)
  147. const defaultOption = document.createElement('option');
  148. defaultOption.value = ''; // 设置为空值
  149. defaultOption.textContent = '请选择用户';
  150. select.appendChild(defaultOption);
  151. filteredUsersInfo.forEach(user => {
  152. if (!selectedUsersSet.has(user.UniqueID) || user.UniqueID === currentValue) {
  153. const option = document.createElement('option');
  154. option.value = user.UniqueID;
  155. option.setAttribute('data-username', user.Username);
  156. option.setAttribute('data-account', user.Account);
  157. option.textContent = `${user.Username} (${user.Account})`;
  158. // 如果是当前选中的值,保持选中状态
  159. if (user.UniqueID === currentValue) {
  160. option.selected = true;
  161. }
  162. select.appendChild(option);
  163. }
  164. });
  165. });
  166. };
  167. newAddSelectBtn.addEventListener('click', () => {
  168. const selectWrapper = document.createElement('div');
  169. selectWrapper.className = 'distributeUser-select-wrapper'; // Flexbox 容器
  170. const select = document.createElement('select');
  171. select.className = 'distributeUser-select'; // 设置下拉框样式
  172. // 添加一个默认的空选项
  173. const defaultOption = document.createElement('option');
  174. defaultOption.value = '';
  175. defaultOption.textContent = '请选择用户'; // 这个选项提示用户选择
  176. defaultOption.selected = true; // 默认选中这个选项
  177. select.appendChild(defaultOption);
  178. // 初始更新下拉框
  179. updateSelectOptions();
  180. // 监听下拉框的变化
  181. select.addEventListener('change', () => {
  182. const previousValue = select.dataset.previousValue;
  183. // 如果之前有选中,移除旧值
  184. if (previousValue) {
  185. selectedUsersSet.delete(previousValue);
  186. }
  187. // 如果有新的选择,添加到 set 中
  188. if (select.value) {
  189. selectedUsersSet.add(select.value);
  190. select.dataset.previousValue = select.value; // 保存当前值为下次移除准备
  191. }
  192. // 更新其他下拉框的选项
  193. updateSelectOptions();
  194. });
  195. // 创建删除按钮,使用与关闭邮件输入框相同的样式
  196. const removeSelectBtn = document.createElement('button');
  197. removeSelectBtn.className = 'DistributeModal-remove-email-btn'; // 使用关闭邮件输入框的按钮样式
  198. removeSelectBtn.innerHTML = '&times;';
  199. removeSelectBtn.addEventListener('click', () => {
  200. const previousValue = select.dataset.previousValue;
  201. if (previousValue) {
  202. selectedUsersSet.delete(previousValue); // 删除时从选中集中移除
  203. }
  204. selectWrapper.remove(); // 删除下拉框
  205. updateSelectOptions(); // 更新其他下拉框的选项
  206. });
  207. // 将下拉框和删除按钮加入到 selectWrapper 中
  208. selectWrapper.appendChild(select);
  209. selectWrapper.appendChild(removeSelectBtn);
  210. // 将 selectWrapper 加入到 userInputs 容器中
  211. userInputs.appendChild(selectWrapper);
  212. // 初始更新其他下拉框
  213. updateSelectOptions();
  214. });
  215. // 点击下半部分的确认按钮
  216. const userConfirmBtn = document.getElementById('distributeUser-confirm-btn');
  217. userConfirmBtn.addEventListener('click', () => {
  218. // 收集用户信息,收集每个下拉框选中的值及其额外数据
  219. const selectedUsers = Array.from(document.querySelectorAll('.distributeUser-select'))
  220. .map(select => {
  221. if (select.value) {
  222. const selectedUserInfo = {
  223. uniqueID: select.value,
  224. username: select.options[select.selectedIndex].getAttribute('data-username'),
  225. account: select.options[select.selectedIndex].getAttribute('data-account')
  226. };
  227. return selectedUserInfo; // 返回用户的所有信息
  228. }
  229. })
  230. .filter(user => user !== undefined); // 过滤掉未选择的空值
  231. // 分别提取 uniqueID, username 和 account 数组
  232. const uniqueIDArray = selectedUsers.map(user => user.uniqueID);
  233. const usernameArray = selectedUsers.map(user => user.username);
  234. const accountArray = selectedUsers.map(user => user.account);
  235. console.log("Unique IDs: ", uniqueIDArray);
  236. console.log("Usernames: ", usernameArray);
  237. console.log("Accounts: ", accountArray);
  238. // 执行用户分发逻辑,传递用户详细信息到 distributeLicense
  239. distributeUser(item, uniqueIDArray, usernameArray, accountArray);
  240. closeDistributeModal(); // 关闭模态框
  241. });
  242. }
  243. // 关闭分发模态框的函数
  244. function closeDistributeModal() {
  245. const modal = document.getElementById('DistributeModal');
  246. modal.style.display = 'none'; // 隐藏模态框
  247. // 清空邮箱和用户输入区域
  248. const emailInputs = document.getElementById('DistributeModal-email-inputs');
  249. emailInputs.innerHTML = ''; // 清空动态生成的邮箱输入框
  250. const userInputs = document.getElementById('DistributeModal-user-inputs');
  251. userInputs.innerHTML = ''; // 清空动态生成的用户选择框
  252. }
  253. function distributeEmails(item, emails, usersInfo) {
  254. console.log('分发 distributeEmails', { item, emails, usersInfo });
  255. // 将 emails 数组转为以逗号分隔的字符串
  256. const emailsString = emails.join(',');
  257. // 从 usersInfo 中获取 currentUserInfo
  258. //const currentUserInfo = usersInfo.find(user => user.role === 'currentUser'); // 假设 currentUser 标识当前用户
  259. if (!currentUserInfo) {
  260. console.error('无法获取当前用户信息');
  261. return;
  262. }
  263. // 构建要发送的数据
  264. const postData = {
  265. emails: emailsString,
  266. LicenseUniqueID: item.UniqueID, // item 中的 UniqueID
  267. Oa_request_id: item.oa_request_id, // item 中的 oa_request_id
  268. OperatorUniqueID: currentUserInfo.UniqueID // currentUserInfo 中的 UniqueID
  269. };
  270. console.log('即将发送的数据:', postData);
  271. showLoadingModal("正在分发邮箱中...");
  272. // 发送 POST 请求到 DistributeLicenseToEmail 接口
  273. fetch('http://127.0.0.1:8080/api/admin/DistributeLicenseToEmail', {
  274. method: 'POST',
  275. headers: {
  276. 'Authorization': `Bearer ${authToken}`, // 使用 authToken
  277. 'Content-Type': 'application/json'
  278. },
  279. body: JSON.stringify(postData) // 将数据转为 JSON 格式
  280. })
  281. .then(response => {
  282. if (!response.ok) {
  283. hideLoadingModal();
  284. throw new Error('Network response was not ok');
  285. }
  286. return response.json();
  287. })
  288. .then(data => {
  289. // 处理成功响应
  290. hideLoadingModal();
  291. console.log('邮件分发成功:', data);
  292. alert('邮件分发成功');
  293. })
  294. .catch(error => {
  295. // 处理错误
  296. hideLoadingModal();
  297. console.error('分发邮件失败:', error);
  298. alert('分发邮件失败,请稍后重试');
  299. });
  300. }
  301. // 执行分发的逻辑
  302. function distributeUser(item, uniqueIDArray, usernameArray, accountArray) {
  303. // 构建要发送的数据对象
  304. const postData = {
  305. Oa_request_id: item.oa_request_id,
  306. LicenseUniqueID: item.UniqueID,
  307. OperatorUniqueID: currentUserInfo.UniqueID, // currentUserInfo 中的 UniqueID
  308. UserUniqueIDs: uniqueIDArray,
  309. UserNames: usernameArray,
  310. UserAccounts: accountArray
  311. };
  312. console.log('Sending user data:', postData);
  313. showLoadingModal("正在分发用户中...");
  314. // 发送 POST 请求到 DistributeLicenseToUser 接口
  315. fetch('http://127.0.0.1:8080/api/admin/DistributeLicenseToUser', {
  316. method: 'POST',
  317. headers: {
  318. 'Content-Type': 'application/json',
  319. 'Authorization': `Bearer ${authToken}` // 使用适当的 authToken
  320. },
  321. body: JSON.stringify(postData) // 将数据转换为 JSON 字符串发送
  322. })
  323. .then(response => {
  324. hideLoadingModal(); // 隐藏 loading 模态框
  325. if (!response.ok) {
  326. // 返回错误信息作为 Promise,以便 catch 块捕获
  327. return response.json().then(errorData => {
  328. // 检查服务器是否返回了特定的错误信息并抛出错误
  329. const errorMessage = errorData.error || '网络响应不正确';
  330. throw new Error(errorMessage);
  331. });
  332. }
  333. return response.json();
  334. })
  335. .then(data => {
  336. console.log('分发成功:', data);
  337. alert('分发成功!');
  338. })
  339. .catch(error => {
  340. hideLoadingModal(); // 在失败时隐藏 loading 模态框
  341. console.error('分发失败:', error.message); // 打印具体的错误信息
  342. alert('分发失败: ' + error.message); // 将错误信息展示给用户
  343. });
  344. }
  345. //--------------分发历史模态框------------------------
  346. // function showDistributionHistory(selectedRowData) {
  347. // fetch('http://127.0.0.1:8080/api/admin/GetlicenseRecord', {
  348. // method: 'POST',
  349. // headers: {
  350. // 'Authorization': `Bearer ${authToken}`,
  351. // 'Content-Type': 'application/json'
  352. // },
  353. // body: JSON.stringify({ uniqueID: selectedRowData.UniqueID, oa_request_id: selectedRowData.oa_request_id })
  354. // })
  355. // .then(response => response.json())
  356. // .then(data => {
  357. // const userDistributionContent = document.getElementById('distributionHistory-user-content');
  358. // const emailDistributionContent = document.getElementById('distributionHistory-email-content');
  359. // // 检查 license_record_to_user 是否是数组,如果不是则默认为空数组
  360. // const userRecords = Array.isArray(data?.data?.license_record_to_user) ? data.data.license_record_to_user : [];
  361. // // 如果 license_record_to_emails 是 null,则设置为空数组
  362. // const emailRecords = Array.isArray(data?.data?.license_record_to_emails) ? data.data.license_record_to_emails : [];
  363. // // 显示用户分发记录
  364. // userDistributionContent.innerHTML = userRecords.length > 0
  365. // ? userRecords.map(record => `<p>已转发给用户: ${record.user_account} 时间: ${formatDateTime(record.up_time)}</p>`).join('')
  366. // : '<p>没有用户分发记录。</p>';
  367. // // 显示邮箱分发记录
  368. // emailDistributionContent.innerHTML = emailRecords.length > 0
  369. // ? emailRecords.map(record => `<p>已发给邮箱: ${record.emails} 时间: ${formatDateTime(record.up_time)}</p>`).join('')
  370. // : '<p>没有邮箱分发记录。</p>';
  371. // // 显示模态框
  372. // document.getElementById('distributionHistory-modal').style.display = 'block';
  373. // })
  374. // .catch(error => {
  375. // console.error('Error fetching distribution history:', error);
  376. // });
  377. // // 关闭模态框 (点击关闭按钮)
  378. // document.querySelector('.distributionHistory-modal-close').addEventListener('click', () => {
  379. // document.getElementById('distributionHistory-modal').style.display = 'none';
  380. // });
  381. // // 点击模态框外部关闭模态框
  382. // window.addEventListener('click', function(event) {
  383. // const modal = document.getElementById('distributionHistory-modal');
  384. // if (event.target === modal) { // 检查点击的是否是模态框背景
  385. // modal.style.display = 'none'; // 关闭模态框
  386. // }
  387. // });
  388. // }
  389. function showDistributionHistory(selectedRowData) {
  390. fetch('http://127.0.0.1:8080/api/admin/GetlicenseRecord', {
  391. method: 'POST',
  392. headers: {
  393. 'Authorization': `Bearer ${authToken}`,
  394. 'Content-Type': 'application/json'
  395. },
  396. body: JSON.stringify({ uniqueID: selectedRowData.UniqueID, oa_request_id: selectedRowData.oa_request_id })
  397. })
  398. .then(response => response.json())
  399. .then(data => {
  400. console.log("showDistributionHistory", data);
  401. // 提取用户记录和邮箱记录
  402. const userRecords = data.data.license_record_to_user || [];
  403. const emailRecords = data.data.license_record_to_emails || [];
  404. // 动态生成用户记录的 HTML
  405. const userContent = userRecords.length > 0 ?
  406. userRecords.map(user => `
  407. <div class="distributionHistory-user">
  408. <div>用户名: ${user.user_account}</div>
  409. <div>唯一用户 ID: ${user.user_unique_id}</div>
  410. <div>更新时间: ${new Date(user.up_time).toLocaleString()}</div>
  411. </div>
  412. `).join('') :
  413. '<div class="distributionHistory-no-record">无用户记录</div>';
  414. // 动态生成邮箱记录的 HTML
  415. const emailContent = emailRecords.length > 0 ?
  416. emailRecords.map(email => `
  417. <div class="distributionHistory-email">
  418. <div>邮箱: ${email.emails}</div>
  419. <div>更新时间: ${new Date(email.up_time).toLocaleString()}</div>
  420. </div>
  421. `).join('') :
  422. '<div class="distributionHistory-no-record">无邮箱记录</div>';
  423. // 将内容插入到模态框中的对应 div
  424. document.getElementById('distributionHistory-user-content').innerHTML = userContent;
  425. document.getElementById('distributionHistory-email-content').innerHTML = emailContent;
  426. // 显示模态框
  427. document.getElementById('distributionHistory-modal').style.display = 'block';
  428. })
  429. .catch(error => {
  430. console.error('Error fetching distribution history:', error);
  431. });
  432. // 关闭模态框 (点击关闭按钮)
  433. document.querySelector('.distributionHistory-modal-close').addEventListener('click', () => {
  434. document.getElementById('distributionHistory-modal').style.display = 'none';
  435. });
  436. // 点击模态框外部关闭模态框
  437. window.addEventListener('click', function(event) {
  438. const modal = document.getElementById('distributionHistory-modal');
  439. if (event.target === modal) {
  440. modal.style.display = 'none';
  441. }
  442. });
  443. }
  444. function formatDateTime(dateString) {
  445. const date = new Date(dateString);
  446. // 获取 UTC 时间
  447. const year = date.getUTCFullYear();
  448. const month = String(date.getUTCMonth() + 1).padStart(2, '0'); // 月份从0开始,所以+1
  449. const day = String(date.getUTCDate()).padStart(2, '0');
  450. const hours = String(date.getUTCHours()).padStart(2, '0');
  451. const minutes = String(date.getUTCMinutes()).padStart(2, '0');
  452. const seconds = String(date.getUTCSeconds()).padStart(2, '0');
  453. // 返回格式化后的字符串,格式为 YYYY-MM-DD HH:mm:ss
  454. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  455. }