call.js 12 KB

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