call.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. import {
  2. startPhoneListener,
  3. stopPhoneListener,
  4. checkIsAutoRecord,
  5. toCallAutoRecorderPage,
  6. navigateToCallRecordingSettings,
  7. jumpToPermissionPage,
  8. allRecorderFilesAction
  9. } from '@/uni_modules/yao-lister';
  10. import permision from "@/js_sdk/wa-permission/permission.js";
  11. import { formatPhoneNumber } from '../../utils/util';
  12. export default {
  13. namespaced: true,
  14. state: {
  15. filelist: [],
  16. isAutoRecord: false, // 通话自动录音状态
  17. hasStoragePermission: false, // 文件访问权限状态
  18. hasReadPhoneStatePermission: false, // 读取手机状态权限
  19. hasCallPhonePermission: false, // 拨打电话权限
  20. hasReadCallLogPermission: false, // 读取通话记录权限
  21. hasReadPhoneNumbersPermission: false, // 读取电话号码权限
  22. form: {
  23. clueId: undefined,
  24. fileUrl : undefined,
  25. fileName : undefined,
  26. type : '3',
  27. list : [],
  28. caller : '',
  29. callee : ''
  30. },
  31. },
  32. mutations: {
  33. SET_FILE_LIST: (state, data) => {
  34. state.filelist = data.data
  35. },
  36. SET_AUTO_RECORD: (state, value) => {
  37. state.isAutoRecord = value;
  38. },
  39. SET_STORAGE_PERMISSION: (state, value) => {
  40. state.hasStoragePermission = value;
  41. },
  42. SET_READ_PHONE_STATE_PERMISSION: (state, value) => {
  43. state.hasReadPhoneStatePermission = value;
  44. },
  45. SET_CALL_PHONE_PERMISSION: (state, value) => {
  46. state.hasCallPhonePermission = value;
  47. },
  48. SET_READ_CALL_LOG_PERMISSION: (state, value) => {
  49. state.hasReadCallLogPermission = value;
  50. },
  51. SET_READ_PHONE_NUMBERS_PERMISSION: (state, value) => {
  52. state.hasReadPhoneNumbersPermission = value;
  53. },
  54. SET_CALLER_PHONE: (state, phoneNumber) => {
  55. state.form.caller = phoneNumber;
  56. },
  57. SET_FORM: (state, data) => {
  58. state.form = data;
  59. },
  60. },
  61. actions: {
  62. getFileList({dispatch,state, commit}) {
  63. dispatch("checkStoragePermission").then(()=>{
  64. if(state.hasStoragePermission){
  65. allRecorderFilesAction(res => {
  66. if(res && res.length > 0) {
  67. // 将文件路径数组转换为包含filePath和fileName的对象数组
  68. const fileListPromise = res.map(filePath => {
  69. return new Promise((resolve) => {
  70. // 从路径中提取文件名
  71. const fileName = filePath.split('/').pop();
  72. // 获取文件信息,包括创建时间
  73. plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
  74. entry.getMetadata((metadata) => {
  75. resolve({
  76. filePath: filePath,
  77. fileName: fileName,
  78. createTime: metadata.modificationTime ? metadata.modificationTime : 0, // 文件创建时间
  79. });
  80. }, (error) => {
  81. // 如果获取metadata失败,返回基本信息
  82. resolve({
  83. filePath: filePath,
  84. fileName: fileName,
  85. createTime: 0, // 设为0,排序时会在最前面
  86. });
  87. });
  88. }, (error) => {
  89. // 如果解析文件路径失败,返回基本信息
  90. resolve({
  91. filePath: filePath,
  92. fileName: fileName,
  93. createTime: 0,
  94. size: 0
  95. });
  96. });
  97. });
  98. });
  99. // 等待所有文件信息获取完成后进行排序
  100. Promise.all(fileListPromise).then((fileList) => {
  101. // 按创建时间排序,最新的文件排在前面(降序)
  102. fileList.sort((a, b) => {
  103. return b.createTime - a.createTime;
  104. });
  105. // 提交文件列表到state
  106. commit('SET_FILE_LIST', { data: fileList });
  107. }).catch((error) => {
  108. console.error('获取文件列表失败:', error);
  109. // 即使排序失败,也尝试提交原始列表
  110. const fallbackFileList = res.map(filePath => {
  111. const fileName = filePath.split('/').pop();
  112. return {
  113. filePath: filePath,
  114. fileName: fileName
  115. };
  116. });
  117. commit('SET_FILE_LIST', { data: fallbackFileList });
  118. });
  119. }
  120. })
  121. }else{
  122. dispatch("requestStoragePermission");
  123. }
  124. })
  125. },
  126. // 获取用户手机号码
  127. getUserPhoneNumber({ commit }) {
  128. return new Promise((resolve, reject) => {
  129. // 首先检查权限
  130. permision.requestAndroidPermission('android.permission.READ_PHONE_NUMBERS')
  131. .then(result => {
  132. if (result === 1) {
  133. // 权限被授予,获取手机号码
  134. try {
  135. const main = plus.android.runtimeMainActivity();
  136. const Context = plus.android.importClass('android.content.Context');
  137. const TelephonyManager = plus.android.importClass('android.telephony.TelephonyManager');
  138. const telephonyManager = main.getSystemService(Context.TELEPHONY_SERVICE);
  139. const phoneNumber = telephonyManager.getLine1Number();
  140. if (phoneNumber && phoneNumber.trim() !== '') {
  141. // 移除国际区号,保留手机号码
  142. const cleanPhoneNumber = formatPhoneNumber(phoneNumber);
  143. commit('SET_CALLER_PHONE', cleanPhoneNumber);
  144. resolve(cleanPhoneNumber);
  145. } else {
  146. // 如果获取不到手机号码,尝试使用备选方法
  147. try {
  148. const SubscriptionManager = plus.android.importClass('android.telephony.SubscriptionManager');
  149. const subscriptionManager = main.getSystemService(Context.TELEPHONY_SERVICE);
  150. const activeSubscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
  151. if (activeSubscriptionInfoList && activeSubscriptionInfoList.size() > 0) {
  152. const subscriptionInfo = activeSubscriptionInfoList.get(0);
  153. const number = subscriptionInfo.getNumber();
  154. if (number && number.trim() !== '') {
  155. // 移除国际区号,保留手机号码
  156. const cleanPhoneNumber = formatPhoneNumber(number);
  157. commit('SET_CALLER_PHONE', cleanPhoneNumber);
  158. resolve(cleanPhoneNumber);
  159. } else {
  160. reject(new Error('无法获取手机号码:SIM卡可能未激活或号码无效'));
  161. }
  162. } else {
  163. reject(new Error('无法获取手机号码:未检测到有效的SIM卡'));
  164. }
  165. } catch (fallbackError) {
  166. console.error('备选方法获取手机号码失败:', fallbackError);
  167. reject(new Error('无法获取手机号码:设备可能不支持或运营商限制'));
  168. }
  169. }
  170. } catch (error) {
  171. console.error('获取手机号码失败:', error);
  172. reject(new Error('获取手机号码失败: ' + error.message));
  173. }
  174. } else {
  175. reject(new Error('没有获取手机号码的权限,请前往设置开启权限'));
  176. }
  177. })
  178. .catch(error => {
  179. console.error('请求权限失败:', error);
  180. reject(error);
  181. });
  182. });
  183. },
  184. // 检查所有权限状态
  185. checkAllPermissions({ commit }) {
  186. return new Promise((resolve, reject) => {
  187. try {
  188. // 检查通话自动录音状态
  189. const autoRecordStatus = checkIsAutoRecord();
  190. commit('SET_AUTO_RECORD', autoRecordStatus);
  191. // 检查文件访问权限
  192. this.dispatch('call/checkStoragePermission').then(storagePermission => {
  193. commit('SET_STORAGE_PERMISSION', storagePermission);
  194. // 检查其他权限
  195. const permissions = [
  196. {
  197. id: 'android.permission.READ_PHONE_STATE',
  198. mutation: 'SET_READ_PHONE_STATE_PERMISSION'
  199. },
  200. {
  201. id: 'android.permission.CALL_PHONE',
  202. mutation: 'SET_CALL_PHONE_PERMISSION'
  203. },
  204. {
  205. id: 'android.permission.READ_CALL_LOG',
  206. mutation: 'SET_READ_CALL_LOG_PERMISSION'
  207. },
  208. {
  209. id: 'android.permission.READ_PHONE_NUMBERS',
  210. mutation: 'SET_READ_PHONE_NUMBERS_PERMISSION'
  211. }
  212. ];
  213. const permissionPromises = permissions.map(perm => {
  214. return permision.requestAndroidPermission(perm.id).then(result => {
  215. commit(perm.mutation, result === 1);
  216. return { id: perm.id, granted: result === 1 };
  217. });
  218. });
  219. Promise.all(permissionPromises).then(results => {
  220. resolve({
  221. autoRecordStatus,
  222. storagePermission,
  223. permissions: results
  224. });
  225. });
  226. });
  227. } catch (error) {
  228. reject(error);
  229. }
  230. });
  231. },
  232. // 检查文件访问权限
  233. checkStoragePermission({ commit }) {
  234. return new Promise((resolve) => {
  235. let hasPermission = false;
  236. try {
  237. // 获取Android版本号
  238. let androidVersion = 0;
  239. uni.getSystemInfo({
  240. success: (res) => {
  241. if (res.system && res.system.includes('Android')) {
  242. const versionMatch = res.system.match(/Android (\d+\.?\d*)/);
  243. if (versionMatch && versionMatch[1]) {
  244. androidVersion = parseFloat(versionMatch[1]);
  245. }
  246. }
  247. if (androidVersion >= 11) {
  248. // Android 11及以上版本,使用MANAGE_EXTERNAL_STORAGE权限
  249. const Environment = plus.android.importClass('android.os.Environment');
  250. hasPermission = Environment.isExternalStorageManager();
  251. commit('SET_STORAGE_PERMISSION', hasPermission);
  252. resolve(hasPermission);
  253. } else {
  254. // Android 11以下版本,使用READ_EXTERNAL_STORAGE权限
  255. permision.requestAndroidPermission('android.permission.READ_EXTERNAL_STORAGE')
  256. .then(result => {
  257. hasPermission = result === 1;
  258. commit('SET_STORAGE_PERMISSION', hasPermission);
  259. resolve(hasPermission);
  260. });
  261. }
  262. }
  263. });
  264. } catch (e) {
  265. hasPermission = false;
  266. commit('SET_STORAGE_PERMISSION', hasPermission);
  267. resolve(hasPermission);
  268. }
  269. });
  270. },
  271. // 请求文件访问权限
  272. requestStoragePermission() {
  273. jumpToPermissionPage();
  274. },
  275. // 跳转到通话录音设置页面
  276. toCallRecorderSettings() {
  277. toCallAutoRecorderPage();
  278. },
  279. // 跳转到系统通话录音界面
  280. toSystemRecorderSettings() {
  281. navigateToCallRecordingSettings();
  282. },
  283. // 打开系统设置
  284. handleOpenSet() {
  285. permision.gotoAppPermissionSetting('android.permission.RECORD_AUDIO');
  286. }
  287. },
  288. }