room.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'moment'], function ($, undefined, Backend, Table, Form, Moment) {
  2. var Controller = {
  3. add: () => {
  4. Controller.form();
  5. },
  6. edit: () => {
  7. Controller.form();
  8. },
  9. form: () => {
  10. const { reactive, onMounted, ref } = Vue
  11. const addEdit = {
  12. setup() {
  13. const state = reactive({
  14. type: new URLSearchParams(location.search).get('type'),
  15. id: new URLSearchParams(location.search).get('id'),
  16. title: new URLSearchParams(location.search).get('title'),
  17. })
  18. const form = reactive({
  19. model: {
  20. way: 'column',
  21. type: 0,
  22. name: '',
  23. date_time: '',
  24. anchor_name: '',
  25. anchor_wechat: '',
  26. sub_anchor_wechat: '',
  27. is_feeds_public: 1,
  28. close_kf: 0,
  29. close_replay: 0,
  30. close_comment: 0,
  31. close_goods: 0,
  32. close_like: 0,
  33. feeds_img: '',
  34. share_img: '',
  35. cover_img: '',
  36. },
  37. rules: {
  38. type: [{ required: true, message: '请选择直播类型', trigger: 'change' }],
  39. way: [{ required: true, message: '请选择播放方式', trigger: 'change' }],
  40. feeds_img: [{ required: true, message: '请选择封面图', trigger: 'change' }],
  41. share_img: [{ required: true, message: '请选择分享图', trigger: 'change' }],
  42. cover_img: [{ required: true, message: '请选择背景图', trigger: 'change' }],
  43. date_time: [{ required: true, message: '请选择开播时间', trigger: 'change' }],
  44. name: [{ required: true, message: '请输入直播间标题', trigger: 'blur' }, { validator: checkTitle, trigger: 'change' }],
  45. anchor_name: [{ required: true, message: '请输入主播昵称', trigger: 'blur' }, { validator: checkNickname, trigger: 'change' }],
  46. anchor_wechat: [{ required: true, message: '请输入主播微信账号', trigger: 'blur' }],
  47. },
  48. });
  49. //获取默认开始时间为当前时间后40分钟
  50. const defaultTime = ref([
  51. new Date(new Date().getTime() + 40 * 60 * 1000),
  52. new Date(2000, 2, 1, 23, 59, 59),
  53. ]);
  54. // 禁止时间
  55. function disabledDate(time) {
  56. return time.getTime() < Date.now() - 86400000;
  57. }
  58. // 获取详情
  59. function getDetail() {
  60. Fast.api.ajax({
  61. url: `shopro/app/mplive/room/detail/id/${state.id}`,
  62. type: 'GET',
  63. }, function (ret, res) {
  64. form.model = res.data;
  65. form.model.date_time = [
  66. Moment(res.data.start_time * 1000).format('YYYY-MM-DD HH:mm:ss'),
  67. Moment(res.data.end_time * 1000).format('YYYY-MM-DD HH:mm:ss'),
  68. ];
  69. return false
  70. }, function (ret, res) { })
  71. }
  72. function onConfirm() {
  73. let submitForm = {
  74. ...form.model,
  75. start_time: Number(new Date(form.model.date_time[0]).getTime() / 1000),
  76. end_time: Number(new Date(form.model.date_time[1]).getTime() / 1000),
  77. }
  78. delete submitForm.date_time
  79. Fast.api.ajax({
  80. url: state.type == 'add' ? 'shopro/app/mplive/room/add' : `shopro/app/mplive/room/edit/id/${state.id}`,
  81. type: 'POST',
  82. data: submitForm,
  83. }, function (ret, res) {
  84. Fast.api.close()
  85. }, function (ret, res) { })
  86. }
  87. function checkTitle(rule, value, callback) {
  88. if (!value) {
  89. return callback(new Error('请输入直播间标题'));
  90. }
  91. const length =
  92. value.match(/[^ -~]/g) == null ? value.length : value.length + value.match(/[^ -~]/g).length;
  93. if (length < 6 || length > 34) {
  94. callback(new Error('直播标题必须为3-17个字(一个字等于两个英文字符或特殊字符)'));
  95. } else {
  96. callback();
  97. }
  98. }
  99. function checkNickname(rule, value, callback) {
  100. if (!value) {
  101. return callback(new Error('请输入主播昵称'));
  102. }
  103. const length =
  104. value.match(/[^ -~]/g) == null ? value.length : value.length + value.match(/[^ -~]/g).length;
  105. if (length < 4 || length > 30) {
  106. callback(new Error('直播标题必须为2-15个字(一个字等于两个英文字符或特殊字符)'));
  107. } else {
  108. callback();
  109. }
  110. }
  111. onMounted(() => {
  112. state.type == 'edit' && getDetail()
  113. })
  114. return {
  115. state,
  116. form,
  117. disabledDate,
  118. onConfirm,
  119. getDetail,
  120. checkTitle,
  121. checkNickname,
  122. defaultTime
  123. }
  124. }
  125. }
  126. createApp('addEdit', addEdit);
  127. },
  128. select: () => {
  129. const { reactive, onMounted } = Vue
  130. const select = {
  131. setup() {
  132. const state = reactive({
  133. data: [],
  134. selected: [],
  135. });
  136. function getData() {
  137. Fast.api.ajax({
  138. url: 'shopro/app/mplive/room/select',
  139. type: 'GET',
  140. }, function (ret, res) {
  141. state.data = res.data;
  142. return false
  143. }, function (ret, res) { })
  144. }
  145. function isSelectable(row) {
  146. return row.status === 101 || row.status === 102 || row.status === 103
  147. }
  148. function onSelectionChange(val) {
  149. state.selected = val
  150. }
  151. function onConfirm() {
  152. Fast.api.close(state.selected)
  153. }
  154. onMounted(() => {
  155. getData()
  156. })
  157. return {
  158. Moment,
  159. state,
  160. isSelectable,
  161. onSelectionChange,
  162. onConfirm,
  163. }
  164. }
  165. }
  166. createApp('select', select);
  167. },
  168. pushurl: () => {
  169. const { reactive, onMounted } = Vue
  170. const pushUrl = {
  171. setup() {
  172. const state = reactive({
  173. id: new URLSearchParams(location.search).get('id'),
  174. pushUrl: '', // 推流地址
  175. serverAddress: '', // 服务器地址
  176. key: '', // 串流密钥
  177. })
  178. function getDetail() {
  179. Fast.api.ajax({
  180. url: `shopro/app/mplive/room/pushUrl/id/${state.id}`,
  181. type: 'GET',
  182. }, function (ret, res) {
  183. state.pushUrl = res.data.pushAddr;
  184. state.serverAddress = state.pushUrl.split('/live/')[0] + '/live/';
  185. state.key = state.pushUrl.split('/live/')[1];
  186. return false
  187. }, function (ret, res) { })
  188. }
  189. function onJump() {
  190. window.open('https://docs.qq.com/doc/DV0hoWHZRdm9oT2pp');
  191. }
  192. onMounted(() => {
  193. getDetail()
  194. })
  195. return {
  196. state,
  197. getDetail,
  198. onClipboard,
  199. onJump
  200. }
  201. }
  202. }
  203. createApp('pushUrl', pushUrl);
  204. },
  205. qrcode: () => {
  206. const { reactive, onMounted } = Vue
  207. const qrcode = {
  208. setup() {
  209. const state = reactive({
  210. id: new URLSearchParams(location.search).get('id'),
  211. cdnUrl: '', // 小程序码
  212. path: '', // 页面路径
  213. key: '', // 串流密钥
  214. })
  215. function getDetail() {
  216. Fast.api.ajax({
  217. url: `shopro/app/mplive/room/qrcode/id/${state.id}`,
  218. type: 'GET',
  219. }, function (ret, res) {
  220. state.cdnUrl = res.data.cdnUrl;
  221. state.path = res.data.pagePath;
  222. return false
  223. }, function (ret, res) { })
  224. }
  225. function saveImg() {
  226. window.open(state.cdnUrl);
  227. }
  228. function onJump() {
  229. window.open(
  230. 'https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/liveplayer/live-player-plugin.html',
  231. );
  232. }
  233. onMounted(() => {
  234. getDetail()
  235. })
  236. return {
  237. state,
  238. getDetail,
  239. onClipboard,
  240. saveImg,
  241. onJump
  242. }
  243. }
  244. }
  245. createApp('qrcode', qrcode);
  246. },
  247. playback: () => {
  248. const { reactive, onMounted } = Vue
  249. const playback = {
  250. setup() {
  251. const state = reactive({
  252. id: new URLSearchParams(location.search).get('id'),
  253. })
  254. // 表格状态
  255. const table = reactive({
  256. data: [],
  257. order: '',
  258. sort: '',
  259. selected: [],
  260. });
  261. function getData() {
  262. Fast.api.ajax({
  263. url: `shopro/app/mplive/room/playback/id/${state.id}`,
  264. type: 'GET',
  265. // data: {
  266. // page: pagination.page,
  267. // list_rows: pagination.list_rows,
  268. // order: state.order,
  269. // sort: state.sort,
  270. // },
  271. }, function (ret, res) {
  272. table.data = res.data
  273. table.data.forEach((item, index) => {
  274. table.data[index].index = index + 1;
  275. });
  276. return false
  277. }, function (ret, res) { })
  278. }
  279. const pagination = reactive({
  280. page: 1,
  281. list_rows: 10,
  282. total: 0,
  283. })
  284. function play(url) {
  285. window.open(url);
  286. }
  287. onMounted(() => {
  288. getData()
  289. })
  290. return {
  291. state,
  292. getData,
  293. pagination,
  294. table,
  295. play
  296. }
  297. }
  298. }
  299. createApp('playback', playback);
  300. },
  301. };
  302. return Controller;
  303. });