# uni-polymerize **Repository Path**: yingbing-developer/uni-polymerize ## Basic Information - **Project Name**: uni-polymerize - **Description**: 基于uni-app 聚合资源的app - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 16 - **Forks**: 11 - **Created**: 2022-12-20 - **Last Updated**: 2025-12-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #应用介绍 * 1、该项目为聚合资源APP,暂只支持安卓APP * 2、聚合资源包括小说、漫画、视频、直播、文章、论坛、音乐等 * 3、该项目支持加载外部来源,也支持内置来源 * 4、为避免版权问题,该项目不提供内置源 * 5、[1.0版本的好用聚合库链接](https://gitee.com/yingbing-developer/uni-polymerize_1.git) * 6、[2.0版本的好用聚合库链接](https://gitee.com/yingbing-developer/uni-polymerize_2.git) * 7、[项目使用图标库](https://www.iconfont.cn/collections/detail?cid=33) * 8、有什么不懂的,可以加 1_0_8_7_7_3_5_9_4_2 去掉横杠即可 #免责声明 * 本免责声明(以下简称“免责声明”或“本声明”)适用于好用聚合项目(以下简称"好用聚合"),在使用人及组织(以下简称"使用者")阅读本声明后若不同意此声明中的任何条款,或对本声明存在质疑,请立刻停止使用此项目。若您已经开始或正在使用此项目,则表示您已阅读并同意本声明的所有条款之约定。 * 1.使用者通过任何形式或方式使用好用聚合即表示您已经同意本声明,本声明立即自动生效。 * 2.使用者使用好用聚合自行承担风险,作者不做任何形式的保证, 因代码质量、系统BUG等任何技术原因而引起的问题,作者也不承担任何法律责任。 * 3.使用者保证好用聚合不用于任何违法犯罪行为,如传播色情、赌博等。 * 4.使用者保证好用聚合所展示内容不涉及版权或隐私等问题。 * 5.使用者保证好用聚合不用于任何商业或盈利等行为。 * 6.使用者使用好用聚合违反上述任何行为所造成的一切后果均由使用者承担。 #源规则详解 * 内置方法 | 方法名 | 说明 | | :---- | :---- | | HTMLParser | 格式化html字符串,用于获取数据[点击查看文档](https://ext.dcloud.net.cn/plugin?id=263) | | Base64 | base64加密和解密方法 | | CryptoJS | CryptoJS工具组 | | Xhr | plus.net.xmlHttpRequest请求方法[点击查看文档](https://www.html5plus.org/doc/zh_cn/xhr.html) | | Http | uni.request请求方法[点击查看文档](https://uniapp.dcloud.net.cn/api/request/request.html) | | GBK | 转gbk编码格式 | | WebWorker | 将js传入浏览器环境执行 | | Utils | 工具栏 | * 示例用法(这里示例用法只是介绍各种方法的使用方式,实际的json布局不是这样的) ```json { //HTMLParser示例用法 "test": "@sync: var document = new HTMLParser(lastResult);return document.getElementsByClassName('className');", //Base64示例用法 "test1": "@sync: var str = lastResult;var base64 = Base64.encode(str);var originStr = Base64.decode(base64);return base64", //CryptoJS示例用法(CryptoJS是很常用的库,内置许多加密方式,具体可以自己研究,这里只做简单示例) "test2": "@sync: var str = lastResult;var md5 = CryptoJS.MD5(str).toString();return md5",//md5加密 //Xhr示例用法 "test3": "@async: var res = await Xhr.get('https://www.test.com', { header: {}, params: {} });return res.data", //Http示例用法 "test4": "@async: var res = await Http.get('https://www.test.com', { header: {}, params: {}, responseType: 'arraybuffer' });return res.data", //GBK示例用法,转换字符为gbk格式主要用于一些网站的搜索,因为一些网站搜索关键词是gbk格式的 "test5": "@sync: var str = '搜索关键词'; var gbkStr = GBK(str); return gbkStr", //WebWorker示例用法,这段代码的意思是将codeStr的字符串,传入浏览器环境执行,window.btoa是浏览器专有属性用于base64加密,"是双引号\",这是规则内定义好了的,会自动转换 "test6": "@async: var codeStr = 'var str = "123"; var base64 = window.btoa(str);'; return await WebWorker(codeStr)", //Utils示例用法,Utils内置多种工具,具体见下方 "test7": "@sync: var num = 15620; return Utils.numberFormat(num, '万')",//格式化数字,带上单位万 } ``` * 工具栏方法(Utils) ```javascript /** * 补零 * @param {Number} val 数字 **/ const zeroize = function (val) { return val >= 10 ? val : '0' + val } /** * 是否是链接 * @param {Number} url 链接 **/ const validateUrl = function (url) { return url.startsWith('http://') || url.startsWith('https://') } /** * 是否是纯数字 * @param {Number} str 文本 **/ const validateNumber = function (str) { return /\d+/.test(str) } /** * 是否是图片链接(包含base64判断) * @param {Number} url 图片链接 **/ const validateImage = function (url) { const imageType = ['png', 'jpg', 'jpeg', 'gif', 'webp'] return url.startsWith('data:image') || imageType.some(t => url.includes(t) || url.includes(t.toUpperCase())) } /** * 复制文本 * @param {Number} text 字符串 **/ const copyText = function (text, message) { uni.setClipboardData({ data: text, success: function () { uni.showToast({ title: message || '复制成功', icon: 'none' }) } }); } /** * 文件大小格式化 * @param {String} available 文件大小 **/ const fileSizeFormat = function (available) { const size = available != 'null' ? available : 0; let fileSizeString; if(size == 0){ fileSizeString = "0B"; }else if(size < 1024){ fileSizeString = size + "B"; }else if(size < 1048576){ fileSizeString = (size/1024).toFixed(2) + "KB"; }else if (size < 1073741824){ fileSizeString = (size/1048576).toFixed(2) + "MB"; }else{ fileSizeString = (size/1073741824).toFixed(2) + "GB"; } return fileSizeString; } /** * 数字格式化 * @param {Number} number 数字 * @param {String} unit 单位 * @param {Number} fixed 小数点最大保留多少位 **/ const numberFormat = function (number, unit = '万', fixed = 2) { const units = {'亿': 100000000, '千万': 10000000, '百万': 1000000, '万': 10000, '千': 1000, '百': 100} const divisor = units[unit] if ( divisor ) { let num = (number / divisor).toString() if ( num.includes('.') && num.split('.')[1].length > fixed ) { num = (number / divisor).toFixed(2) } return num + unit } return num } /** * 时间格式化 * @param {String} time 时间戳or时间 **/ const dateFormat = function (time, formats = 'yyyy-mm-dd hh:mm:ss') { let arr = formats.split(' ') let dateFormats = '' let timeFormats = '' arr.forEach(item => { if ( item.indexOf('yy') > -1 ) { dateFormats = item } else { timeFormats = item } }) const d = new Date(time); let result = '' if ( dateFormats.indexOf('yyyy') > -1 ) { result += d.getFullYear() + '-' } if ( dateFormats.indexOf('mm') > -1 ) { result += zeroize(d.getMonth() + 1) + '-' } if ( dateFormats.indexOf('dd') > -1 ) { result += zeroize(d.getDate()) + ' ' } if ( timeFormats.indexOf('hh') > -1 ) { result += zeroize(d.getHours()) + ':' } if ( timeFormats.indexOf('mm') > -1 ) { result += zeroize(d.getMinutes()) + ':' } if ( timeFormats.indexOf('ss') > -1 ) { result += zeroize(d.getSeconds()) + ':' } return result.substring(0, result.length - 1) } /** * 秒数转化为时分秒 * @param {String} value 秒数 **/ const timeFormat = function (value, format = 'HH:mm:ss') { let hours ='00' if ( format.indexOf('HH') > -1 ) { hours = Math.floor(value / 60 / 60) >= 10 ? Math.floor(value / 60 / 60) : '0' + Math.floor(value / 60 / 60) } let minutes = '00' if ( format.split(':')[0] == 'HH' ) { minutes = Math.floor(value / 60 % 60) >= 10 ? Math.floor(value / 60 % 60) : '0' + Math.floor(value / 60 % 60) } if ( format.split(':')[0] == 'mm' ) { minutes = Math.floor(value / 60) >= 10 ? Math.floor(value / 60) : '0' + Math.floor(value / 60) } let seconds = Math.floor(value % 60) >= 10 ? Math.floor(value % 60) : '0' + Math.floor(value % 60); return format.indexOf('HH') > -1 ? hours + ':' + minutes + ':' + seconds : minutes + ':' + seconds } /** * 时间转化为秒数 * @param {String} time 时间(HH:mm:ss) **/ const timeToSeconds = function (time){ let arr = time.split(':') if ( arr.length == 2 ) arr.unshift('00') const seconds = parseInt(arr[0]) * 3600 + parseInt(arr[1]) * 60 + ( arr[2].indexOf('.') > -1 ? parseInt(arr[2].split('.')[0]) + parseInt(arr[2].split('.')[1]) / 1000 : parseInt(arr[2]) ) ; return seconds } /** * 移除url地址域名 * @param {String} str http地址 **/ const removeUrl = function (url) { let str = url.replace(/^http:\/\/[^/]+/, ''); return str.substr(1); } /** * 获取文件后缀 * @param {String} name 带后缀的文件名称 **/ const suffix = function (name) { //获取图片后缀 let fileName = name.lastIndexOf("."); let fileNameLength = name.length; let fileFormat = name.substring(fileName + 1, fileNameLength); return fileFormat.split('?')[0]; } /** * 清除文件后缀 * @param {String} name 带后缀的文件名称 */ const removeSuffix = function (name) { //获取图片后缀 let fileName = name.lastIndexOf("."); if ( fileName > -1 ) { let fileNameFormat = name.substring(0, fileName); return fileNameFormat; } else { return name } } /** * 链接参数拼接 * @param {String} url 请求链接 * @param {String} params 请求参数 */ function urlPrams (url, params) { params = typeof params == 'object' ? params : [params] for (var k in params) { let value = params[k] !== undefined ? params[k] : '' value = typeof value == 'string' ? value : JSON.stringify(value) url +=(url.indexOf('?') < 0 ? '?' : '&') + `${k}=${encodeURIComponent(value)}` } return url } /** * 转化url参数为对象 * @param {Array} href 携带参数的链接 */ const convertUrlQueryObject = function(href) { const index = href.indexOf('?') const url = index > -1 ? href.substring(0, index) : href const search = index > -1 ? href.substring(index+1) : '' const vars = search.split('&') const obj = {} for (let i=0;i date2 ) { console.log("开始时间不能大于结束时间!"); return false; } let seconds = date2.getTime() / 1000 - date1.getTime() / 1000; return type == 'minutes' ? (seconds / 60) : type == 'hours' ? (seconds / 60 / 60) : seconds; } /** * 判断值类型返回字符 * @param {datetime} value 需要判断类型的值 */ const typeCall = function (value) { const type = Object.prototype.toString.call(value); return type.slice(8, type.length - 1) } /** * 生成随机字符串 * @param {Number} len 长度 */ const randomString = function (len) { len = len || 32; var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/ var maxPos = $chars.length; var pwd = ''; for (let i = 0; i < len; i++) {   pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; } /** * 生成随机数字字符 * @param {Number} len 长度 */ const randomNumberString = function (len) { let min = 0; let max = len - 1; let arr = []; while ( arr.length < len ) { let value = Math.floor(Math.random() * (max - min + 1)) + min; if ( arr.indexOf(value) == -1 ) { arr.push( value ) } } return arr.join(''); } /** * 生成随机ID */ const randomId = function () { return new Date().getTime().toString() + Math.round(Math.random() * 10000); } /** * 生成随机不重复整数 * @param {Number} len 长度 * @param {Number} start 开始数字 */ const randomSoleNumbers = function (len) { let min = 0; let max = len - 1; let arr = []; while ( arr.length < len ) { let value = Math.floor(Math.random() * (max - min + 1)) + min; if ( arr.indexOf(value) == -1 ) { arr.push( value ) } } return arr; } /** * 16进制颜色转化为rgb * @param {String} hex 16进制颜色 */ const hexToRgb = function (hex) { hex = hex.length == 7 ? hex : '#' + hex.slice(1, 4) + hex.slice(1, 4) let str="rgb(" const r = parseInt(hex.slice(1,3),16).toString(); //ff slice不包括end const g = parseInt(hex.slice(3,5),16).toString(); //00 const b = parseInt(hex.slice(5,7),16).toString(); //ff str += r+","+g+","+b+")"; return str } /** * rgb转化为16进制颜色 * @param {String} rgb */ const rgbToHex = function (rgb) { rgb = rgb.replace('rgb(', '').replace(')', '') rgb = rgb.split(',') const r = parseInt(rgb[0], 10).toString(16); const g = parseInt(rgb[1], 10).toString(16); const b = parseInt(rgb[2], 10).toString(16); return '#' + (r.length == 2 ? r : r + r) + (g.length == 2 ? g : g + g) + (b.length == 2 ? b : b + b) } /** * 16进制颜色转化为rgba * @param {String} hex 16进制颜色 */ const hexToRgba = function (hex, opacity) { hex = hex.length == 7 ? hex : '#' + hex.slice(1, 4) + hex.slice(1, 4) let str="rgba(" const r = parseInt(hex.slice(1,3),16).toString(); //ff slice不包括end const g = parseInt(hex.slice(3,5),16).toString(); //00 const b = parseInt(hex.slice(5,7),16).toString(); //ff str += r+","+g+","+b+","+opacity+")"; return str } /** * rgba转化为16进制颜色 * @param {String} rgba */ const rgbaToHex = function (rgba) { rgba = rgba.replace('rgba(', '').replace(')', '') rgba = rgba.split(',') const r = parseInt(rgba[0], 10).toString(16); const g = parseInt(rgba[1], 10).toString(16); const b = parseInt(rgba[2], 10).toString(16); return '#' + (r.length == 2 ? r : r + r) + (g.length == 2 ? g : g + g) + (b.length == 2 ? b : b + b) } /** * 10进制颜色转化为rgb * @param {String} decimal 10进制颜色 */ const decimalToRgb = function (decimal) { const r = (decimal >> 16) & 255; const g = (decimal >> 8) & 255; const b = decimal & 255; return 'rgb(' + r + ',' + g + ',' + b + ')' } /** * unicode转换为中文或字符串 * @param {String} str */ const uncode = function (str) { return str.replace(/&#(x)?([^&]{1,5});?/g, function (a, b, c) { return String.fromCharCode(parseInt(c, b ? 16 : 10)); }) } /** * 删除对象指定属性 * @param {Object} object 目标对象 * @param {String} key 目标属性(多个以,分隔) */ const deleteProperty = function (object, key) { const obj = {} const keys = key.split(',').map(s => s.trim()) Object.keys(object).forEach(k => { if ( keys.indexOf(key) == -1 ) obj[key] = object[key] }) return obj } /** * 删除对象指定属性 * @param {Object} object 目标对象 */ const removeEmptyProperty = function (object) {//移除空值属性 if (typeof object !== 'object' || object === null) { return object; } if (Array.isArray(object)) { return object.map(item => removeEmptyProperty(item)).filter(item => item !== null && item !== undefined && item !== "" && !(Array.isArray(item) && item.length === 0) && !(typeof item === 'object' && Object.keys(item).length === 0)); } const newObj = {}; for (const key in object) { if (object.hasOwnProperty(key)) { const value = removeEmptyProperty(object[key]); if (value !== null && value !== undefined && value !== "" && !(Array.isArray(value) && value.length === 0) && !(typeof value === 'object' && Object.keys(value).length === 0)) { newObj[key] = value; } } } return newObj; } /** * 判断数组是否包含另一个数组 * @param {a} Array 包含数组 * @param {b} Array 被包含数组 */ const isContained = function (a, b){ if( typeCall(a) != 'Array' || typeCall(b) != 'Array' ) return false; if(a.length < b.length) return false; for ( let i = 0; i < b.length; i++ ) { for(let j = 0; j < a.length; j++){ if(JSON.stringify(b[i]) == JSON.stringify(a[j])) break; if ( j == a.length - 1 ) return false } } return true; } ``` * 关键词(注意标签内的空格是为了不被markdown编译加的,实际使用要去掉) | 方法名 | 说明 | | :---- | :---- | | < /if> | 条件判断 | | < /elseif> | 否则条件判断 | | < /then> | 满足条件判断执行 | | < /else> | 不满足条件判断执行 | | < /js> | 执行js | * 特殊转义字符(一些特殊字符存储在字符串中会有冲突,比如双引号,为了统一特殊字符的输入方法,所以在规则内使用一些定义好的字符替代这些特殊字符,转义字符分号前的空格时没有的,这是为了不被markdown编译加的,实际使用要去掉) | 转义字符 | 原字符 | 说明 | | :---- | :----: | :---- | | &es; | \\ | 斜杠 | | &wrap; | \n | 换行 | |   ; | | 空格 | | &tabu; | \t | 制表符 | | " ; | \" | 双引号 | | &apos ; | \' | 单引号 | | < ; | < | 左尖括号 | | > ; | > | 右尖括号 | | &oe; | { | 左大括号 | | &ce; | } | 右大括号 | * 声明符 | 方法名 | 说明 | | :---- | :---- | | @text: | 文本声明符(直接返回文本) | | @sync: | 同步方法声明符 | | @async: | 异步方法声明符 | | @sel: | dom方法声明符(实例化html字符串提取dom) | | @json: | json方法声明符(获取json属性) | | @for: | for循环声明符 | | @map: | map循环声明符(返回最终的列表) | | @filter: | 过滤声明符(过滤不满足条件的循环项) | | @find: | 查找声明符(找到满足条件的一项) | | @sort: | 排序声明符(排序) | | @replace: | 替换声明符(替换单个字符串) | | @replaceAll: | 替换全部声明符(替换所有满足条件的字符串) | | @plain: | 纯文本声明符(去除文本中的所有html标签、换行符和空格只保留文本内容) | | @split: | 分割声明符(分割字符串为数组) | | @string: | 转化字符串声明符(将数组转化为字符串等同于toString) | | @dateFormat: | 日期格式转换声明符 | | @join: | 数组转字符串声明符 | | @slice: | 字符串和数组切割声明符 | | @trim: | 修剪声明符(去除字符串左右空格) | | @have: | 包含声明符(判断字符串中是否包含某个字符串) | | @unhave: | 不包含声明符(判断字符串中是否不包含某个字符串) | | @equal: | 相等声明符(判断两个参数是否相等) | | @unequal: | 不等声明符(判断两个参数是否不等) | | @eval: | 字符串转函数声明符(尝试转换字符串为函数) | | @query: | 链接参数获取并转换对象声明符(将url链接上拼接的参数转化为对象并返回) | | @match: | 正则匹配声明符(使用正则表达式匹配字符串中的字符) | | @reverse: | 反转声明符(反转数组) | | @encodeUri: | 转义声明符(等同于js的encodeURIComponent) | | @decodeUri: | 反转义声明符(等同于js的decodeURIComponent) | | @objectKeys: | 对象key属性整合数组声明符(等同于js的Object.keys) | | @objectArray: | 对象值转换数组声明符(将对象转化为数组) | | @upper: | 大写字母声明符(转化小写字母为大写字母) | | @lower: | 小写字母声明符(转化大写字母为小写字母) | | @response: | 返回结果声明符(直接返回最原始的请求结果) | | @console: | 打印日志声明符(类似于js的console.log,打印日志会在debug开启的开发者工具里面显示) | * 内置变量(仅在@sync: @async: @map: @sort: @for: @filter:等声明符中才可使用) | 变量名 | 说明 | | :---- | :---- | | response | 缓存变量,获取当前请求的缓存内容 | | response.header | 缓存变量中的header属性,获取当前请求的服务器返回的header | | response.content | 缓存变量中的content属性,获取当前请求的返回的内容(已处理的内容) | | response.originContent | 缓存变量中的originContent属性,获取当前请求的返回的原始内容(未处理的内容) | | response.params | 缓存变量中的params属性,获取当前请求可能用到的所有参数(包含跳转页面携带的参数,page,搜索关键词keyword等,如果是资源请求还包含自定义的参数,对于你想拿到的参数都可以在在这个参数中尝试获取) | | response.index | 缓存变量中的index属性,如果当前规则处理属于列表(即规则对象中包含list属性)那么index可以获取到当前执行到第几项的索引 | | lastResult | 上个步骤规则处理的最终结果 | | result | @for:声明符中才有的变量,是@for:声明符返回的最终结果,默认值是空数组 | | baseUrl | 基础域名,获取当前源的基础域名(动态获取的域名也从这里获取) | | globalData | 公共变量,源规则中globalData中自定义的变量 | | globalMethod | 公共方法,源规则中globalMethod中自定义的属性(由于globalMethod的特殊性,仅支持在@async:声明符中使用) | * 连接符 | 符号 | 说明 | | :---- | :---- | | >> | 步骤连接符,最常用的连接符,表示进行下一个步骤 | | && | 合并连接符,只能用于@sel:声明符,表示使用这个符号连接的操作会分开处理,最后结果会合并在一起变成数组返回 | * 使用示例(这里的使用示例仅演示使用方式,实际json布局不是这样): ```json //@text:使用示例 { "test1": "@text:玄幻小说",//通常形式(输出 "玄幻小说") "test2": "玄幻小说",//当没有其它声明符时可省略(输出 "玄幻小说") "test3": "@text:@sync:return '玄幻小说'",//当有其它声明符时不可省略(输出 "@sync:return '玄幻小说'") "test4": "@text:你好这是一本@sync:return '玄幻小说'"//配合可以选择编译任意声明符而不是直接输出文本(输出 "你好这是一本玄幻小说") } //@sync:使用示例 { "test1": "@sync:return '玄幻小说'",//普通用法(输出 "玄幻小说") "test2": "@sync:return '玄幻小说'@sync:return lastResult.replace('小说','')",//继承上类规则结果lastResult(输出 "玄幻") "test3": "@sync:return Utils.suffix('这是一个文件.mp4')",//调用内置方法(输出 "mp4") "test4": "@sync:return baseUrl + '/test.png'",//使用内置属性baseUrl(baseUrl为自己设置的基础域名) "test5": "@sync:return globalData.customValue",//使用内置属性globalData,customValue为自定义公共变量 "test6": "@sync:return response.content"//使用内置属性response返回最原始的请求结果 } //@async:使用示例 { "test1": "@async:return await Http.get('https://www.baidu.com')",//普通用法(输出 "百度页面的html") "test2": "@sync:return 'https://www.baidu.com'@async:return await Http.get(lastResult)",//继承上类规则结果lastResult(输出 "百度页面的html") "test3": "@async:return await Http.get(baseUrl + 'test.html')",//使用内置属性baseUrl(baseUrl为自己设置的基础域名) "test4": "@async:return await Http.get(globalData.href + 'test.html')",//使用内置属性globalData,href为自定义公共变量 "test5": "@async:return await Http.get('https://www.test.com/test.html', { header: response.header })",//使用内置属性response,请求返回的头部信息可以从这里获取(考虑到一些接口可能会有加密或者解密会使用到header中的数据) "test6": "@async:return await globalMethod.customHandle(lastResult)"//调用自定义方法globalMethod中的方法,globalMethod中的方法只能在@async:声明符中使用 } //@json:使用示例(前面的@sync:声明符返回数据只是为了方便理解,实际使用大部分都用不到,@json:声明符就是操作json数据的,如果你的请求接口返回的就是json数据,那直接用@json:声明符获取就行) { "test1": "@sync:return {'name': '名字', value: '123'}@json:name",//调用对象(输出 "名字") "test2": "@sync:return {list: ['你好', '不好', '很好']}@json:list[1]"//调用数组(输出 "不好") } //@sel:使用示例(元素选择器,很常用) { "test1": "@sel:id.text>>text",//id选择器 假设有html文本 玄幻小说(输出 "玄幻小说") "test2": "@sel:class.text[0]>>text",//class选择器 假设有html文本 玄幻小说(输出 "玄幻小说") "test3": "@sel:tag.span[0]>>text",//tag选择器 假设有html文本 玄幻小说(输出 "玄幻小说") "test4": "@sel:class.item[0]>>class.text[1]>>text", //多层选择 假设有html文本
玄幻小说悬疑小说
(输出 "悬疑小说") "test5": "@sel:class.text[0]>>attr.title",//获取标签属性 假设有html文本 (输出 "玄幻小说") "test6": "@sel:id.item>>content",//获取innerHTML内容 假设有html文本
玄幻小说
(输出 "玄幻小说") "test6": "@sel:id.item>>html",//获取outerHTML内容 假设有html文本
玄幻小说
(输出 "
玄幻小说
") "test6": "@sel:class.text1>>text&&class.text2>>text",//使用&&合并结果 假设有html文本
玄幻小说
科幻小说
(输出 ["玄幻小说", "科幻小说"]) //标签属性匹配 "test7": "@sel:tag.div[class][0]>>text",//获取包含class属性的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "玄幻小说") "test8": "@sel:tag.div[class=text2][0]>>text",//获取class属性等于text2的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "科幻小说") "test8": "@sel:tag.div[class!=text2][0]>>text",//获取class属性不等于text2的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "玄幻小说") "test9": "@sel:tag.div[class*=text2][0]>>text",//获取class属性包含text2的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "玄幻小说") "test9": "@sel:tag.div[class!*=text2][0]>>text",//获取class属性不包含text2的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "科幻小说") "test10": "@sel:tag.div[class~=text2][0]>>text",//获取class属性单词(空格分隔)包含text2的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "科幻小说") "test10": "@sel:tag.div[class!~=text2][0]>>text",//获取class属性单词(空格分隔)不包含text2的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "玄幻小说") "test12": "@sel:tag.div[class^=text2][0]>>text",//获取class属性以text2开头的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "科幻小说") "test13": "@sel:tag.div[class$=text2][0]>>text",//获取class属性以text2结尾的div标签 假设有html文本
玄幻小说
科幻小说
(输出 "玄幻小说") } //@for:使用示例 { "test1": "@sync:return [{name: '玄幻'},{name: '悬疑'}]@for:result.push(item.name)"//普通用法(输出 "['玄幻', '悬疑']") } //@map:使用示例 { "test1": "@sync:return [{name: '玄幻'},{name: '悬疑'}]@map:item.name",//普通用法(输出 "['玄幻', '悬疑']") "test2": "@sync:return [{name: '玄幻', value: 1},{name: '悬疑', value: 2}]@map:{ return item.name + item.value}"//复杂用法(输出 "['玄幻1', '悬疑2']") } //@filter:使用示例 { "test1": "@sync:return [{name: '玄幻'},{name: '悬疑'},{name: '古风'}]@filter:item.name == '玄幻'",//普通用法(输出 "[{name: '玄幻'}]") "test2": "@sync:return [{name: '玄幻', value: 1},{name: '悬疑', value: 2}]@filter:{ return item.name == '悬疑' && item.value == 2}"//复杂用法(输出 "[{name: '悬疑', value: 2}]") } //@sort:使用示例 { "test1": "@sync:return [4,1,6,8,10]@sort:a-b",//普通用法(输出 "[1,4,6,8,10]") "test2": "@sync:return [{name: '悬疑', value: 2}, {name: '玄幻', value: 1}, {name: '古风', value: 3}]@sort:{ return a.value - b.value }"//复杂用法(输出 "[{name: '玄幻', value: 1}, {name: '悬疑', value: 2}, {name: '古风', value: 3}]") } //@find:使用示例 { "test1": "@sync:return [{name: '悬疑'}, {name: '玄幻'}, {name: '古风'}]@find:item.name == '悬疑'",//普通用法(输出 "{name: '悬疑'}") "test2": "@sync:return [{name: '悬疑'}, {name: '玄幻'}, {name: '古风'}]@find:{ var name = '悬疑';return item.name == name }"//复杂用法(输出 "{name: '悬疑'}") } //@replace:使用示例 { "test1": "@sync:return '玄幻小说'@replace:小说>>漫画",//普通用法(输出 "玄幻漫画") "test2": "@sync:return '玄幻小说'@replace:小说"//替换字符串为空(输出 "玄幻") } //@replaceAll:使用示例 { "test1": "@sync:return '玄幻小说科幻小说'@replaceAll:小说>>漫画",//普通用法(输出 "玄幻漫画科幻漫画") "test2": "@sync:return '玄幻小说科幻小说'@replaceAll:小说"//替换字符串为空(输出 "玄幻科幻") } //@plain:使用示例 { "test1": "@sync:return '

玄幻小说

'@plain:"//普通用法(输出 "玄幻小说") } //@split:使用示例 { "test1": "@sync:return '玄幻,科幻'@split:,",//普通用法(输出 "['玄幻', '科幻']") "test2": "@sync:return '玄幻,科幻'@split:,>>1"//指定下标(输出 "科幻") } //@string:使用示例 { "test1": "@sync:return ['玄幻','科幻','古风']@string:",//普通用法(输出 "玄幻,科幻,古风") "test2": "@sync:return 10@string:2",//转换2进制(输出 "1010") "test3": "@sync:return 10@string:16"//转换16进制(输出 "A") } //@dateFormat:使用示例 { "test1": "@sync:return 1695608527060@dateFormat:",//时间戳转换(输出 "2023-09-25 10:23:21") "test2": "@sync:return 1695608527060@dateFormat:yyyy-mm-dd",//只转换日期(输出 "2023-09-25") "test3": "@sync:return 1695608527060@dateFormat:hh:mm:ss"//只转换时间(输出 "10:23:21") } //@join:使用示例 { "test1": "@sync:return ['玄幻','科幻','古风']@join:;"//普通用法(输出 "玄幻;科幻;古风") } //@slice:使用示例 { "test1": "@sync:return '玄幻小说'@slice:0>>1",//截取字符串(输出 "玄") "test1": "@sync:return ['玄幻', '科幻']@slice:0>>1",//截取数组(输出 "['玄幻']") "test1": "@sync:return '玄幻小说'@slice:1"//不传最后位置默认截取到最后(输出 "幻小说") } //@trim:使用示例 { "test1": "@sync:return ' 这是一段2边有空格的文本 '@trim:"//普通用法(输出:"这是一段2边有空格的文本") } //@have:使用示例 { "test1": "@sync:return '这本小说已完结'@have:已完结"//普通用法(输出:"true") } //@equal:使用示例 { "test1": "@sync:return 500@equal:50"//普通用法(输出:"false") } //@unequal:使用示例 { "test1": "@sync:return 500@unequal:50"//普通用法(输出:"true") } //@eval:使用示例 { "test1": "@sync:return 'function () { return [1,2,3,4,5] }'@eval:",//普通用法(输出:"[1,2,3,4,5]") "test2": "@sync:return '[1,2,3,4,5]'@eval:function"//普通字符串强制转化为function用法(输出:"[1,2,3,4,5]") } //@query:使用示例 { "test1": "@sync:return '/article/read.html?id=150&c=123'@query:",//普通用法(输出:"{id: 150, c: 123}") } //@match:使用示例 { "test1": "@sync:return '你看过这本小说吗这是一本不错的小说'@match:小说>>小说",//普通用法(输出:"['小说吗这是一本不错的小说', '吗这是一本不错的']") "test2": "@sync:return '/article/150215.html'@match:article&es;/>>.html>>1"//复杂用法(输出:"150215") } //@reverse:使用示例 { "test1": "@sync:return [1,2,3]@reverse:"//普通用法(输出:"[3,2,1]") } //@encodeUri:使用示例 { "test1": "@sync:return '?id=123&c=123'@encodeUri:"//普通用法(输出:"id%3D123%26c%3D123") } //@decodeUri:使用示例 { "test1": "@sync:return 'id%3D123%26c%3D123'@decodeUri:"//普通用法(输出:"?id=123&c=123") } //@objectKeys:使用示例 { "test1": "@sync:return {name: 1, value: 2}@objectKeys:"//普通用法(输出:"['name', 'value']") } //@objectArray:使用示例 { "test1": "@sync:return {name: 1, value: 2}@objectArray:"//普通用法(输出:"[1, 2]") } //@upper:使用示例 { "test1": "@sync:return 'name'@upper:"//普通用法(输出:"NAME") } //@lower:使用示例 { "test1": "@sync:return 'NAME'@lower:"//普通用法(输出:"name") } //@response:使用示例 { "list": "@sel:class.item",//获取class为item的所有元素,输出数组 "title": "@sel:text",//获取每一项中的文本内容 "description": "@response:@sel:class.intro>>text"//通过response声明该项不从列表中获取数据,直接指定从元数据中获取 } //@console:使用示例 { "list": "@sel:class.item@console:打印日志",//获取class为item的所有元素,然后打印到开发者工具,打印输出结果为:打印日志,(这里是上一次规格返回的结果) } //使用示例 { "test1": "@sync:return true@sync: return '正确'",//(输出:"正确") "test2": "@sync:return false@sync: return '正确'@sync: return '错误'"//(输出:"错误") } //list列表示例 { "list": "@sel:class.items",//特殊属性(一定要保证返回的是列表) "filter": "@sel:class.title[0]>>text@have:",//特殊字段 用于筛选列表(这里表示筛选出包含类名为title且包裹文本内容的元素) "...": "..."//自定义属性除了特殊字段其余为自定义属性 } ``` #源规则基本结构 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | id | String | ---- | ---- | 应用唯一id | | name | String | ---- | ---- | 应用名称 | | type | String | ---- | ---- | 应用类型 | | creator | String | ---- | ---- | 应用创建者 | | description | String | ---- | ---- | 应用简介 | | versionCode | Number | 100 | ---- | 应用版本号 | | versionName | String | 1.0.0 | ---- | 应用版本名称 | | href | String | ---- | ---- | 应用主域名(在请求缺少域名时会使用该域名拼接) | | logo | String | ---- | ---- | 应用图标网络路径 | | themeColor | String | ---- | ---- | 主题颜色 | | isAdult | Number | 0 | 1/0 | 是否包含敏感内容 | | dynamic | Object | ---- | ---- | 动态域名请求规则 | | globalConfig | Object | ---- | ---- | 公共配置 | | globalData | Object | ---- | ---- | 公共变量 | | globalMethod | Object | ---- | ---- | 公共方法 | | globalStyle | Object | ---- | ---- | 公共样式 | | tabbar | Object | ---- | ---- | 应用底部导航栏 | | pages | Array | ---- | ---- | 应用页面集合 | * 示例用法 ```json { "id": "......",//应用id "name": "......",//应用名称 "type": "......",//应用类型 "creator": "......",//应用创建者 "versionCode": 100,//应用版本号 "versionName": "1.0.0",//应用版本 "description": "......",//应用简介 "href": "......",//应用链接 "logo": "......",//应用图标 "themeColor": "#F5F5F5",//主题颜色 "isAdult": 0,//是否敏感 "onLaunch": "",//应用启动生命周期 "dynamic": {},//动态链接请求 "config": {},//公共配置 "globalConfig": {},//公共配置 "globalMethod": {},//公共方法 "globalData": {},//应用公共变量 "globalStyle": {},//应用公共样式 "tabbar": {},//应用tabbar "pages": []//应用页面列表 } ``` #globalConfig(公共配置) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cacheEfficiency | Number | 10000 | ---- | 请求缓存有效时间 | | timeout | Number | 10000 | ---- | 请求超时时间 | | imageDecrypt | String | ---- | ---- | 图片解密 | | imageReferer | String | ---- | ---- | 图片源域名(用于加载有防盗链的图片) | | audioReferer | String | ---- | ---- | 音频源域名(用于加载有防盗链的音频) | | ---- | Any | ---- | ---- | 自定义方法 | * 示例用法 ```json { "id": "......",//应用id "name": "......",//应用名称 "type": "......",//应用类型 "creator": "......",//应用创建者 "versionCode": 100,//应用版本号 "versionName": "1.0.0",//应用版本 "description": "......",//应用简介 "href": "......",//应用链接 "logo": "......",//应用图标 "isAdult": 0,//是否敏感 "globalConfig": { //请求内容缓存有效时间 "cacheEfficiency": 10000, //请求超时时间 "timeout": 10000, //图片解密 "imageDecrypt": "@sync: return lastResult.slice(0, 8)",//lastResult为图片链接 //图片防盗链域名 "imageReferer": "http://www.test.com", //音频防盗链域名 "audioReferer": "http://www.audio.com" } } ``` #onLaunch(应用首次启动) * 示例用法(主要用于异步初始化一些数据) ```json { "id": "......",//应用id "name": "......",//应用名称 "type": "......",//应用类型 "creator": "......",//应用创建者 "versionCode": 100,//应用版本号 "versionName": "1.0.0",//应用版本 "description": "......",//应用简介 "href": "......",//应用链接 "logo": "......",//应用图标 "isAdult": 0,//是否敏感 "onLaunch": "@async: const res = await Http.post('https://www.test.com/refreshtoken'); globalData.token = res.data.token;", "globalData": { "token": "" } } ``` #request(请求) * 注意事项 - 在请求中的属性出现{{}}双大括号包裹的内容表示动态绑定 例:"url": "/cat/1.html?&page={{page}}",page表示当前的页数 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | url | String | ---- | ---- | 请求链接 | | nextUrl | String | ---- | ---- | 下一页请求链接(部分网站获取下一页数据的方式是从上一页请求数据中得到的,通过该属性返回下一页请求需要的链接) | | device | String | 电脑 | 电脑/手机 | 请求平台 | | method | String | get | get/post/postget | 请求方式 | | params | Object | ---- | ---- | 请求参数 | | header | Object | ---- | ---- | 请求头 | | timeout | Number | 10000 | ---- | 请求超时时间 | | webview | Number | 0 | 0/1 | 是否开启webview加载内容(主要用于内容异步加载,且有加密和混肴等等的网页) | | delay | Number | 1000 | ---- | 延迟获取webview内容(单位ms) | | visits | Number | 1 | ---- | webview加载多少次后开始获取内容(考虑到一些网址会有多次中转跳转) | | charset | String | utf-8 | utf-8/gbk | 请求编码格式 | | response | String | ---- | ---- | 请求结果处理规则 | | responseType | String | text | arraybuffer/text | 返回结果类型 | | sslVerify | Number | 0 | 0/1 | 验证 ssl 证书 | | cacheEfficiency | Number | 10000 | ---- | 请求结果缓存时间 | * 可能出现的动态绑定数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | page | Number | 1 | ---- | 当前页数 | | keyword | String | ---- | ---- | 搜索关键字(页面开启搜索功能后) | | $ + 序号(例:$1) | String | ---- | $1/$2/$3/... | filter(筛选页)选中的选项值 | | left | String | ---- | ---- | linkage(双向联动页面)左边选项栏选中值 | | top | String | ---- | ---- | linkage(双向联动页面)顶部选项栏选中值 | | 任意公共变量 | ---- | ---- | ---- | globalData属性中定义的公共变量 | | 任意链接参数 | ---- | ---- | ---- | 进行应用内url跳转时携带的自定义参数(详情见下方#页面跳转) | * 示例用法 ```json { "request": { "url": "https://www.test.com/cat/1.html?&page={{page}}",//请求链接 "header": {//自定义头部 "Content-Type": "application/json" }, "params": {//自定义参数 "sort": "{{$1}}", "sign": "{{$2}}" }, "device": "电脑"//请求平台 }//请求 } ``` * globalData示例用法 ```json { "globalData": { "myarg": "这是一个自定义参数" },//这里只是示例,globalData位置实际不在这里,应该要放在源规则第一层,详情见上方#源规则基本结构 "request": { "url": "https://www.test.com/cat/1.html?&page={{page}}&myarg={{myarg}}",//请求链接 "device": "电脑"//请求平台 }//请求 } ``` #dynamic(动态域名请求规则)(同上方request结构相同,只是多了result结果返回) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | result | String | ---- | ---- | 最后返回的结果规则 | * 示例用法 ```json { "id": "......",//应用id "name": "......",//应用名称 "type": "......",//应用类型 "creator": "......",//应用创建者 "versionCode": 100,//应用版本号 "versionName": "1.0.0",//应用版本 "description": "......",//应用简介 "href": "......",//应用链接 "logo": "......",//应用图标 "isAdult": 0,//是否敏感 "dynamic": { "url": "https://www.test.com",//请求链接 "deivce": "电脑",//请求平台 "result": "@sel:class.link>>attr.href"//返回结果 } } ``` #globalData(公共变量) * 示例用法 ```json { "id": "......",//应用id "name": "......",//应用名称 "type": "......",//应用类型 "creator": "......",//应用创建者 "versionCode": 100,//应用版本号 "versionName": "1.0.0",//应用版本 "description": "......",//应用简介 "href": "......",//应用链接 "logo": "......",//应用图标 "isAdult": 0,//是否敏感 "globalData": { "customData": "test"//自定义变量 }, "pages": [{ "name": "index", "type": "module", "style": { "navigationTitle": "首页" }, "components": [ { "name": "card", "request": { "url": "/article/list?cat=1&page={{page}}&customdata={{customData}}",//动态绑定参数,可以直接使用globalData中的customData属性 "device": "电脑" }, "dynamicData": { "list": "@sel:class.article-list[0]>>class.media", "url": "articledetail?custom=@sync: return globalData.customData"//在sync中使用需要加上globalData } } ] }] } ``` #globalMethod(公共方法) * 示例用法 ```json { "id": "......",//应用id "name": "......",//应用名称 "type": "......",//应用类型 "creator": "......",//应用创建者 "versionCode": 100,//应用版本号 "versionName": "1.0.0",//应用版本 "description": "......",//应用简介 "href": "......",//应用链接 "logo": "......",//应用图标 "isAdult": 0,//是否敏感 "globalMethod": { "customDecrypt": "@sync: return lastResult.slice(0, 8)"//自定义解密方法 }, "pages": [{ "name": "index", "type": "module", "style": { "navigationTitle": "首页" }, "components": [ { "name": "card", "request": { "url": "/article/list?cat=1&page={{page}}", "device": "电脑", "response": "@async: return await globalMethod.customDecrypt(lastResult)"//提前处理请求内容,由于globalMethod的特殊性,只能放在@async中使用 }, "dynamicData": { "list": "@sel:class.article-list[0]>>class.media", "title": "@sel:class.media-object[0]>>attr.alt", "cover": "@sel:class.media-object[0]>>attr.src", "subtitle": "@sel:class.text-muted[0]>>text", "url": "articledetail?id=@sel:tag.a[0]>>attr.href@match:article&es;/>>.html>>1" } } ] }] } ``` #页面样式 * globalStyle(默认样式) * darkStyle(暗黑样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | navigationTitle | String | ---- | ---- | 顶部导航栏标题 | | navigationTextColor | String | ---- | ---- | 顶部导航栏文字颜色 | | navigationCapsuleStyle | String | auto | dark/light/auto | 胶囊按钮样式 | | navigationBackground | String | ---- | ---- | 顶部导航栏背景(支持网络图片路径) | | navigationBackgroundOpacity | Number | 1 | ---- | 顶部导航栏背景透明度 | | enableNavigationTransparent | Number | 0 | 1/0 | 开启顶部导航栏背景透明 | | enableNavigationCapsuleBorder | Number | 0 | 1/0 | 开启胶囊按钮边框 | | enableNavigationSearchInput | Number | 0 | 1/0 | 开启顶部导航栏搜索框 | | navigationSearchInputUrl | String | ---- | ---- | 顶部导航栏搜索框点击跳转链接(支持在线网址和规则页面) | | navigationInputBackgroundColor | String | ---- | ---- | 顶部导航栏搜索框背景色 | | navigationInputTextColor | String | ---- | ---- | 顶部导航栏搜索框提示文字颜色 | | enablePulldown | Number | 0 | 1/0 | 开启下拉刷新 | | enableLoadmore | Number | 0 | 1/0 | 开启上拉加载更多 | | enableBackTop | Number | 0 | 1/0 | 开启返回顶部按钮 | | enableBounce | Number | 0 | 1/0 | 开启页面回弹 | | enableSwiper | Number | 0 | 1/0 | 开启左右滑动(仅支持filter/linkage/column/user类型页面) | | enableSearch | Number | 0 | 1/0 | 开启搜索功能(仅支持module/column/filter/linkage类型页面) | | enableSearchFirstLoad | Number | 0 | 1/0 | 开启搜索功能后第一次进入页面是否主动加载一次列表数据(仅支持module/column/filter/linkage类型页面) | | enableTopGap | Number | 1 | 1/0 | 开启顶部间隔 | | enableFilterIcon | Number | 1 | 1/0 | 强制开启筛选页面的筛选图标(仅支持filter页面) | | backTopImage | String | ---- | ---- | 自定义返回按钮网络图片路径 | | pulldownRefreshImage | String | ---- | ---- | 自定义下拉刷新图片网络路径 | | background | String | ---- | ---- | 页面背景(支持网络图片路径) | | backgroundBlur | Number | 10 | ---- | 页面背景高斯模糊 | | pageMarginGap | Number | 20 | ---- | 页面左右边距 | | componentStyle | Object | ---- | ---- | 组件公共样式(详情见下方) | | cellStyle | Object | ---- | ---- | 列表公共样式(详情见下方) | | subsectionMainIndex | Number | 0 | ---- | 选项栏tabs的主要索引(仅支持filter页面) | | subsectionColumn | Number/String | auto | auto/任意整数 | 选项栏tabs列数(仅支持filter/linkage/column/user类型页面) | | subsectionFilterColumn | Number/String | 4 | auto/任意整数 | 选项栏tabs展开后的列数(仅支持filter类型页面) | | subsectionBackgroundColor | String | ---- | ---- | 选项栏tabs背景色(仅支持filter/linkage/column/user类型页面) | | subsectionSelectedColor | String | ---- | ---- | 选项栏tabs选中高亮色(仅支持filter/linkage/column/user类型页面) | | loadingColor | String | ---- | ---- | 加载提示色 | | themeColor | String | ---- | ---- | 应用主题色(统一设置高亮色) | | coverWidth | Number | ---- | ---- | 封面宽度(仅支持video/novel/comic/audio/picture等资源页面) | | coverHeight | Number | ---- | ---- | 封面高度(仅支持video/novel/comic/audio/picture等资源页面) | | coverBorderRadius | Number | ---- | ---- | 封面圆角(仅支持video/novel/comic/audio/picture等资源页面) | | coverMode | String | aspectFill | ---- | 封面裁切模式(仅支持video/novel/comic/audio/picture等资源页面) | * componentStyle(组件公共样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | marginTop | Number | 30 | ---- | 上外边距 | | marginBottom | Number | 0 | ---- | 下外边距 | | marginLeft | Number | 默认值和页面边距(pageMarginGap)相同 | ---- | 左外边距 | | marginRight | Number | 默认值和页面边距(pageMarginGap)相同 | ---- | 右外边距 | | borderTop | Number/String | ---- | ---- | 上边框 | | borderBottom | Number/String | ---- | ---- | 下边框 | | backgroundColor | String | #ffffff | ---- | 组件背景色 | | backgroundOpacity | Number | 1 | 0-1 | 组件背景透明度 | | borderRadius | Number | 15 | ---- | 组件圆角 | * cellStyle(列表公共样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | paddingLeft | Number | 默认值和页面边距(pageMarginGap)相同 | ---- | 左内边距 | | paddingRight | Number | 默认值和页面边距(pageMarginGap)相同 | ---- | 右内边距 | | marginLeft | Number | 0 | ---- | 左外边距 | | marginRight | Number | 0 | ---- | 右外边距 | | backgroundColor | String | #ffffff | ---- | 背景色 | | backgroundOpacity | Number | 1 | 0-1 | 背景透明度 | * 示例用法 ```json { "id": "......",//应用id "name": "......",//应用名称 "type": "......",//应用类型 "creator": "......",//应用创建者 "versionCode": 100,//应用版本号 "versionName": "1.0.0",//应用版本 "description": "......",//应用简介 "href": "......",//应用链接 "logo": "......",//应用图标 "isAdult": 0,//是否敏感 "globalStyle": { "navigationTitle": "首页",//导航栏标题 "navigationTextColor": "#333333",//导航栏文字颜色 //组件公共样式 "componentStyle": { "marginTop": 0,//关闭顶部间隔 "borderTop": 1,//开启顶部边框 "borderBottom": "1px dashed #eee"//开启底部边框 }, //单元格公共样式 "cellStyle": { "backgroundColor": "#eee"//设置单元格背景色 }, "darkStyle": {//暗黑模式 "navigationTextColor": "#999999",//导航栏文字颜色 "componentStyle": { "borderBottom": "1px dashed #999"//开启底部边框 } } } } ``` #tabbar(底部导航栏) * style(默认样式) * darkStyle(暗黑样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | background | String | ---- | ---- | 底部导航栏背景(支持网络图片路径) | | color | String | ---- | ---- | 底部导航栏默认颜色 | | selectedColor | String | ---- | ---- | 底部导航栏选中高亮颜色 | | selectedBackground | String | ---- | ---- | 底部导航栏选中背景(支持网络图片路径) | | backgroundOpacity | Number | 1 | ---- | 底部导航栏背景透明 | * list(底部导航栏列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | name | String | ---- | ---- | 绑定页面名称 | | icon | String | ---- | ---- | 默认图标 可使用网络图片路径或者[图标库](https://www.iconfont.cn/collections/detail?cid=33) | | selectedIcon | String | ---- | ---- | 选中显示图标 可使用网络图片路径或者[图标库](https://www.iconfont.cn/collections/detail?cid=33) | | text | String | ---- | ---- | 文字 | * 示例用法 ```json { "id": "......",//应用id "name": "......",//应用名称 "type": "......",//应用类型 "creator": "......",//应用创建者 "versionCode": 100,//应用版本号 "versionName": "1.0.0",//应用版本 "description": "......",//应用简介 "href": "......",//应用链接 "logo": "......",//应用图标 "isAdult": 0,//是否敏感 "tabbar": { "style": { "background": "#ffffff",//tabbar背景 "color": "#cccccc",//默认颜色 "selectedColor": "#333333",//选中颜色 "darkStyle": { "background": "#050505",//tabbar背景 "color": "#999999",//默认颜色 "selectedColor": "#cccccc",//选中颜色 }//暗黑模式 结构和style一样 }, "list": [{ "name": "index",//页面名称 "icon": "home",//默认图标 "selectedIcon": "home_fill",//选中图标 "text": "首页"//文字 },{ "name": "filter",//页面名称 "icon": "form",//默认图标 "selectedIcon": "form_fill",//选中图标 "text": "分类"//文字 }]//tabbar列表 },//应用tabbar } ``` #pages(页面) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | name | String | ---- | ---- | 页面名称 | | style | Object | ---- | ---- | 页面样式(详情查看上方globStyle) | | type | String | ---- | module/filter/column/linkage/short/user/novel/comic/article/picture/video/audio/live | 页面类型 | #路由页面跳转 * 路由跳转能携带的固定参数 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | selected | Number | ---- | ---- | column、short页面tabs选项栏默认选中项 | | current | Number | ---- | ---- | short页面默认滑动位置 | | $ + '序号'(如:$1,$2,$3...等等) | String | ---- | ---- | filter页面选项栏默认选中值 | | top | String | ---- | ---- | linkage页面顶部选项栏默认选中值 | | left | String | ---- | ---- | linkage页面左边选项栏默认选中值 | | globalStyle | Any | ---- | ---- | globalStyle样式中任意参数(可动态改变跳转页面该样式) | * 1、通过每个页面的name来实现跳转,例如: ```json { "pages": [{ "name": "index", "type": "module", "style": { "navigationTitle": "首页" }, "components": [ { "name": "search-input", "style": { "url": "search",//跳转name为search的规则页面 "placeholder": "点击搜索内容",//提示文字 "borderRadius": 10//圆角 } } ] },{ "name": "search", "type": "module", "style": { "navigationTitle": "搜索页面", "enableSearch": 1//开启搜索功能 } }]//应用页面列表 } ``` * 2、跳转时可以携带参数,例如: ```json { "pages": [{ "name": "index", "type": "module", "style": { "navigationTitle": "列表" }, "cell": { "staticData": [{ "title": "......", "cover": "......", "subtitle": "......", "url": "detail?id=123"//跳转时携带id参数 }] } }, { "name": "detail", "type": "novel", "style": { "navigationTitle": "详情" }, "detail": { "request": { "url": "/detail/{{id}}.html"//可以在请求当中动态绑定传过来的参数 }, "dynamicData": { "title": "......", "subtitle": "......", "cover": "......" } } }]//应用页面列表 } ``` * 3、跳转时可以携带固定参数来实现修改跳转页面的样式,例如: ```json { "pages": [{ "name": "index", "type": "module", "style": { "navigationTitle": "列表" }, "cell": { "staticData": [{ "title": "......", "cover": "......", "subtitle": "......", "url": "detail?id=123&background=https://www.test.com/images/151545.png"//跳转时background参数,该参数会覆盖掉跳转页面style样式中的background }] } }, { "name": "detail", "type": "novel", "style": { "navigationTitle": "详情", "background": "#f5f5f5"//跳转参数中携带background,则该样式会被覆盖 }, "detail": { "request": { "url": "/detail/{{id}}.html"//可以在请求当中动态绑定传过来的参数 }, "dynamicData": { "title": "......", "subtitle": "......", "cover": "......" } } }]//应用页面列表 } ``` * 4、跳转时可以携带固定参数来实现修改拥有选项栏页面的默认选项(比如column, filter, linkage, short页面): ```json { "pages": [{ "name": "index", "type": "module", "style": { "navigationTitle": "首页" }, "components": [ { "name": "menu", "style": { "column": 2, "columnGap": 15 }, "staticData": [,{ "icon": "close", "title": "韩漫", "url": "type?$2=2"//跳转参数中携带($+数字),filter页面默认选中第二个选项栏值为1的选项 },{ "icon": "close", "title": "日漫", "url": "art?selected=1"//跳转时携带selected参数,column页面默认显示第二栏 },{ "icon": "close", "title": "短视频", "url": "short?current=5"//跳转时携带current参数,short页面默认滑动到第四项 },{ "icon": "close", "title": "排行", "url": "rank?top=3&left=4"//跳转时携带top和left参数,linkage页面默认选中顶部导航栏值为3的选项和侧边导航栏值为4的选项 }] } ] }] } ``` #module(模块页) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cell | Object | ---- | ---- | 单元格列表(具体见下方cell单元格讲解) | | components | Array | ---- | ---- | 组件集合(具体见下方components组件讲解) | * 示例用法 ```json { "pages": [{ "name": "index", "type": "module", "style": { "navigationTitle": "首页" }, "components": [ { "name": "search-input", "style": { "url": "search",//跳转name为search的规则页面 "placeholder": "点击搜索内容",//提示文字 "borderRadius": 10//圆角 } } ], "cell": { "style": { "cellName": "h-cell", "cellImageWidth": 160, "cellImageHeight": 220, "cellDescriptionLines": 4 }, "request": { "url": "/index", "device": "电脑" }, "dynamicData": { "list": "@sel:class.rank-book-list[0]>>tag.a", "title": "@sel:class.book-name[0]>>text", "cover": "@sel:class.book-cover[0]>>tag.img[0]>>attr.src", "subtitle": "@sel:class.book-extra[0]>>text", "description": "@sel:class.book-intro[0]>>text", "url": "book?id=@sel:attr.href@match:book&es;/>>.html>>1" } } }]//应用页面列表 } ``` #filter(筛选页) * 注意事项 - filter页面如果有多个选项栏默认会折叠只显示一行,样式中subsectionMainIndex用于控制折叠后显示哪一个选项栏 - 选中的选项栏的值会以($ + 序号)的方式传给cell单元格列表的请求中,如第一行选项栏的值为($1)例:"url": "/cat/{{$1}}.html" | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | subsection | Object | ---- | ---- | 选项栏tabs | | cell | Object | ---- | ---- | 单元格列表(具体见下方cell单元格讲解) | | components | Object | ---- | ---- | 组件列表(具体见下方components组件讲解) | * subsection(选项栏) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | staticData | Array | ---- | ---- | 静态数据 | | request | Object | ---- | ---- | 请求(详情见上方request请求讲解) | | dynamicData | Object | ---- | ---- | 动态数据 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | label | String | ---- | ---- | 选项栏标题 | | children | Array/Object | ---- | ---- | 选项栏集合 | * children | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | label | String | ---- | ---- | 选项栏标题 | | value | String | ---- | ---- | 选项栏绑定值 | * 示例用法 ```json { "pages": [{ "name": "type", "type": "filter", "style": { "navigationTitle": "小说分类", "background": "#fff", "subsectionMainIndex": 2, "enableSwiper": 0, "enableNavigationSearchInput": 1, "navigationSearchInputUrl": "search", "enableLoadmore": 1 }, "darkStyle": { "background": "#131313" }, "subsection": { "request": { "url": "/cat/-1.html", "device": "电脑" }, "staticData": [{ "label": "排序", "children": [{ "label": "综合排序", "value": "hot" },{ "label": "最多援力", "value": "supp" },{ "label": "最多收藏", "value": "fav" },{ "label": "最多字数", "value": "wrods" },{ "label": "最近更新", "value": "updates" }] }],//静态数据 "dynamicData": [{ "label": "@sel:class.search-condition[1]>>class.condition-type[0]>>text", "children": { "list": "@sel:class.search-condition[1]>>tag.li", "label": "@sel:tag.a[0]>>text", "value": "@sel:tag.a[0]>>attr.href@split:sign=>>1" } },{ "label": "@sel:class.search-condition[2]>>class.condition-type[0]>>text", "children": { "list": "@sel:class.search-condition[2]>>class.special", "label": "@sel:tag.a[0]>>text", "value": "@sel:tag.a[0]>>attr.href@match:cat&es;/>>.html>>1" } }]//动态数据 }, "cell": { "style": { "cellImageWidth": 160, "cellImageHeight": 220, "cellDescriptionLines": 4 }, "request": { "url": "/cat/{{$3}}.html", "device": "电脑", "params": { "sort": "{{$1}}", "sign": "{{$2}}", "page": "{{page}}" } }, "dynamicData": { "list": "@sel:class.rank-book-list[0]>>class.rank-book", "title": "@sel:class.book-name[0]>>text", "cover": "@sel:class.book-cover[0]>>tag.img[0]>>attr.src", "subtitle": "@sel:class.book-extra[0]>>text", "description": "@sel:class.book-intro[0]>>text", "url": "book?id=@sel:class.book-mask-left[0]>>attr.href@match:book&es;/>>.html>>1" } } }]//应用页面列表 } ``` #column(分栏页) * 注意事项 - column页面结构和module(模块页)基本一样,只是多了一层subsection包裹 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | subsection | Array | ---- | ---- | 选项栏tabs和页面类容 | * subsection | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | label | String | ---- | ---- | 分栏标题 | | components | Array | ---- | ---- | 组件集合(具体见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(具体见下方cell单元格讲解) | * 示例用法 ```json { "name": "article", "type": "column", "style": { "navigationTitle": "文章列表", "background": "#fff", "enableNavigationSearchInput": 1, "enableLoadmore": 1, "navigationSearchInputUrl": "search", "enableSwiper": 0 }, "darkStyle": { "background": "#131313" }, "subsection": [{ "label": "轻之专栏", "cell": { "style": { "cellName": "v-cell", "cellColumn": 1, "cellImageHeight": 280 }, "request": { "url": "/article/list?cat=1&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.article-list[0]>>class.media", "title": "@sel:class.media-object[0]>>attr.alt", "cover": "@sel:class.media-object[0]>>attr.src", "subtitle": "@sel:class.text-muted[0]>>text", "url": "articledetail?id=@sel:tag.a[0]>>attr.href@match:article&es;/>>.html>>1" } } },{ "label": "作者须知&公告", "cell": { "style": { "cellName": "v-cell", "cellColumn": 1, "cellImageHeight": 280 }, "request": { "url": "/article/list?cat=2&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.article-list[0]>>class.media", "title": "@sel:class.media-object[0]>>attr.alt", "cover": "@sel:class.media-object[0]>>attr.src", "subtitle": "@sel:class.text-muted[0]>>text", "url": "articledetail?id=@sel:tag.a[0]>>attr.href@match:article&es;/>>.html>>1" } } }] } ``` #linkage(双向联动页) * 注意事项 - 选中的顶部选项栏的值会top方式传给cell单元格列表的请求中,例:"url": "/cat/{{top}}.html" - 选中的左边选项栏的值会left方式传给cell单元格列表的请求中,例:"url": "/cat/{{left}}.html" | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | topSubsection | Object | ---- | ---- | 顶部选项栏tabs | | leftSubsection | Object | ---- | ---- | 左边选项栏tabs | | cell | Object | ---- | ---- | 单元格列表(具体见下方cell单元格讲解) | | components | Object | ---- | ---- | 组件列表(具体见下方components组件讲解) | * topSubsection(顶部选项栏) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | staticData | Array | ---- | ---- | 静态数据 | | request | Object | ---- | ---- | 请求(详情见上方request请求讲解) | | dynamicData | Object | ---- | ---- | 动态数据 | * leftSubsection(左边选项栏) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | staticData | Array | ---- | ---- | 静态数据 | | request | Object | ---- | ---- | 请求(详情见上方request请求讲解) | | dynamicData | Object | ---- | ---- | 动态数据 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | label | String | ---- | ---- | 选项栏标题 | | value | String | ---- | ---- | 选项栏值 | * 示例用法 ```json { "name": "rank", "type": "linkage", "style": { "navigationTitle": "排行榜", "background": "#f5f5f5", "subsectionColumn": 3, "enableSwiper": 1, "enableNavigationSearchInput": 1, "navigationSearchInputUrl": "search", "enableLoadmore": 1 }, "darkStyle": { "background": "#050505" }, "topSubsection": { "staticData": [{ "label": "周排行", "value": "week" },{ "label": "月排行", "value": "month" },{ "label": "新书排行", "value": "new" }] }, "leftSubsection": { "request": { "url": "/list/top", "device": "手机" }, "dynamicData": { "list": "@sel:class.top-slide-menu[0]>>class.slide-menu-item", "label": "@sel:text", "value": "@sel:attr.value" } }, "cell": { "style": { "cellImageWidth": 160, "cellImageHeight": 220, "cellDescriptionLines": 4 }, "request": { "url": "/hub/getTopBooks?unit={{left}}&page={{page}}&time={{top}}", "device": "电脑" }, "dynamicData": { "list": "@json:data.books", "title": "@json:name", "cover": "@json:coverUrl", "subtitle": "@text:@json:author/@json:hot", "description": "@json:about", "url": "book?id=@json:id" } } } ``` #short(短视频页) * 注意事项 - 想要实现短视频滑动加载必须设置enableLoadmore为1 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | subsection | Object | ---- | ---- | 选项栏 | | items | Object | ---- | ---- | 视频列表 | | cell | Object | ---- | ---- | 单元格列表(具体见下方cell单元格讲解) | | components | Object | ---- | ---- | 组件列表(具体见下方components组件讲解) | | comments | Object | ---- | ---- | 评论列表 | * items | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | cover | String | ---- | ---- | 封面图片网络路径 | | src | String | ---- | ---- | 播放视频链接 | | isLive | Number | 0 | 1/0 | 是否直播视频 | | isAdult | Number | 0 | 1/0 | 是否敏感内容 | * comments(评论列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | avatar | String | ---- | ---- | 头像网络图片路径 | | title | String | ---- | ---- | 评论标题 | | subtitle | String | ---- | ---- | 评论二级标题 | | content | String | ---- | ---- | 评论内容 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | | subComments | Object | ---- | ---- | 二级评论列表(结构和评论列表相同) | | masterComments | Object | ---- | ---- | 顶部评论列表(结构和评论列表相同) | * 示例用法 ```json { "name": "recome", "type": "short", "style": { "navigationTitle": "推荐", "enableNavigationTransparent": 1, "enablePulldown": 1, "enableLoadmore": 1 }, "subsection": { "staticData": [{ "label": "推荐", "value": "recome" },{ "label": "同城", "value": "city" }] }, "items": { "request": { "url": "{{requestUrl}}", "method": "post", "header": { "Cookie": "{{requestCookie}}" }, "params": "{{globalData.requestParams[params.selected]}}" }, "dynamicData": { "list": "@sync:return lastResult.data.visionNewRecoFeed ? lastResult.data.visionNewRecoFeed.feeds : lastResult.data.sameCityData.feeds", "title": "@json:photo.caption", "description": "播放:@json:photo.viewCount喜欢:@json:photo.likeCount", "cover": "@json:photo.coverUrl", "src": "@json:photo.photoUrl", "author": "@json:author@console:", "photoId": "@json:photo.id" } }, "components": [{ "name": "card", "style": { "cellName": "h-cell", "cellColumn": 1, "cellImageWidth": 100, "cellImageHeight": 100, "cellImageBorderRadius": 100 }, "staticData": [{ "title": "{{params.author.name}}", "cover": "{{params.author.headerUrl}}" }] }], "comments": { "request": { "url": "/rest/v/photo/comment/list", "method": "post", "params": { "photoId": "{{photoId}}", "pcursor": "{{params.list.length > 0 ? params.list[params.list.length - 1].id : ''}}" }, "header": { "Cookie": "{{requestCookie}}" } }, "dynamicData": { "list": "@sync:return lastResult.rootCommentsV2.concat(lastResult.rootComments)@sort:a.timestamp - b.timestamp", "avatar": "@json:headurl", "title": "@json:author_name", "subtitle": "@json:timestamp@dateFormat:", "content": "@json:content", "url": "user?id=@json:author_id", "id": "@json:comment_id", "subComments": { "list": "@json:comment_id@sync:return response.content.subCommentsMap[lastResult].subComments", "avatar": "@json:headurl", "title": "@json:author_name", "subtitle": "@json:timestamp@dateFormat:", "content": "@json:content", "id": "@json:comment_id", "url": "user?id=@json:author_id" } } } } ``` #novel(小说页) * 注意事项 - 每个属性(例如:detail和items)中都默认包含staticData,request和dynamicData属性,这里因为内容太多就不显示了 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | detail | Object | ---- | ---- | 详情信息 | | items | Object | ---- | ---- | 章节列表 | | context | Object | ---- | ---- | 章节正文 | | comments | Object | ---- | ---- | 评论列表 | | components | Array | ---- | ---- | 组件列表(详情见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(详情见下方cell单元格讲解) | * detail(详情信息) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面图片网络路径 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | tags | Object | ---- | ---- | 标签列表 | | isAdult | Number | 0 | 1/0 | 是否敏感内容 | * tags(标签列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * items(章节列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | Array | ---- | ---- | 标题 | | ...(这里可以任意添加属性) | Any | ---- | ---- | 自定义属性(用于请求正文内容时使用,你可以自定义为任何内容) | * context(章节正文) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | content | String | ---- | ---- | 正文内容 | * comments(评论列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | avatar | String | ---- | ---- | 头像网络图片路径 | | title | String | ---- | ---- | 评论标题 | | subtitle | String | ---- | ---- | 评论二级标题 | | content | String | ---- | ---- | 评论内容 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | | subComments | Object | ---- | ---- | 二级评论列表(结构和评论列表相同) | | masterComments | Object | ---- | ---- | 顶部评论列表(结构和评论列表相同) | * 示例用法 ```json { "name": "book", "type": "novel", "style": { "navigationTitle": "小说详情", "enableLoadmore": 1, "componentBackgroundOpacity": 0.7 }, "detail": { "request": { "url": "/book/{{id}}.html", "device": "电脑" }, "dynamicData": { "title": "@sel:class.book-title[0]>>text", "cover": "@sel:class.book-cover[0]>>tag.img[0]>>attr.src", "subtitle": "@sel:class.book-data[0]>>text", "description": "@sel:class.about-text[0]>>text", "tags": { "list": "@sel:class.book-cats>>tag.a", "title": "@sel:text", "url": "@sel:attr.href@have:cattype?$3=@sel:attr.href@match:cat&es;/>>.html>>1@sel:attr.href@have:tagtag?navigationTitle=@sel:text&tag=@sel:attr.href@split:tag=>>1matchBooks?navigationTitle=@sel:text&mid=@sel:attr.href@split:mid=>>1" } } }, "items": { "request": { "url": "/book/{{id}}.html", "device": "电脑" }, "dynamicData": { "list": "@sel:class.chapter", "title": "@sel:tag.a[0]>>text", "href": "@sel:tag.a[0]>>attr.href" } }, "context": { "request": { "url": "{{href}}", "device": "电脑" }, "dynamicData": { "content": "@sel:class.article-text[0]>>content@replaceAll:<p>><p style="margin-top: 10px"" } }, "comments": { "request": { "url": "/comment/items?type=book&tid={{id}}&pageSize=15&page={{page}}&_={{RandomNumberString(13)}}" }, "dynamicData": { "list": "@json:items", "avatar": "@json:author.avatar", "title": "@json:author.nick", "subtitle": "@json:date@sync:return lastResult*1000@dateFormat:", "content": "@json:content", "url": "user?id=@json:author.id", "subComments": { "list": "@json:replies.items", "avatar": "@json:author.avatar", "title": "@json:author.nick", "subtitle": "@json:date@sync:return lastResult*1000@dateFormat:", "content": "@json:content", "url": "user?id=@json:author.id" } } }, "components": [{ "name": "card", "style": { "cardTitle": "作者", "cellName": "h-cell", "cellColumn": 1, "cellImageWidth": 80, "cellImageHeight": 80, "cellDescriptionLines": 1, "cellImageBorderRadius": 80 }, "request": { "url": "/book/{{id}}.html", "device": "电脑" }, "dynamicData": { "list": "@sel:class.novelist", "title": "@sel:class.name[0]>>tag.a[0]>>text", "cover": "@sel:tag.img[0]>>attr.src", "description": "@sel:class.about[0]>>text", "url": "user?id=@sel:class.name[0]>>tag.a[0]>>attr.href@replace:/user/info?id=" } },{ "name": "card", "style": { "cardTitle": "作者其它作品", "cellName": "h-cell", "cellColumn": 1, "moreText": "更多", "moreUrl": "userwork?id=@sel:class.section-helper[0]>>tag.a[0]>>attr.href@split:id=>>1" }, "request": { "url": "/book/{{id}}.html", "device": "电脑" }, "dynamicData": { "list": "@sel:class.from-author", "title": "@sel:class.suggest-book-name[0]>>text", "cover": "@sel:class.suggest-cover[0]>>tag.img[0]>>attr.src", "description": "@sel:class.suggest-book-desc[0]>>text", "url": "book?id=@sel:tag.a[0]>>attr.href@match:book&es;/>>.html>>1" } }] } ``` #comic(漫画页) * 注意事项 - 每个属性(例如:detail和items)中都默认包含staticData,request和dynamicData属性,这里因为内容太多就不显示了 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | detail | Object | ---- | ---- | 详情信息 | | items | Object | ---- | ---- | 章节列表 | | context | Object | ---- | ---- | 章节正文 | | comments | Object | ---- | ---- | 评论列表 | | components | Array | ---- | ---- | 组件列表(详情见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(详情见下方cell单元格讲解) | * detail(详情信息) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面图片网络路径 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | tags | Object | ---- | ---- | 标签列表 | | isAdult | Number | 0 | 1/0 | 是否敏感内容 | * tags(标签列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * items(章节列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | Array | ---- | ---- | 标题 | | content | String | ---- | ---- | 正文内容 | | ...(这里可以任意添加属性) | Any | ---- | ---- | 自定义属性(用于请求正文内容时使用,你可以自定义为任何内容) | * context(章节正文) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | content | Array | ---- | ---- | 正文内容 | * comments(评论列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | avatar | String | ---- | ---- | 头像网络图片路径 | | title | String | ---- | ---- | 评论标题 | | subtitle | String | ---- | ---- | 评论二级标题 | | content | String | ---- | ---- | 评论内容 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | | subComments | Object | ---- | ---- | 二级评论列表(结构和评论列表相同) | | masterComments | Object | ---- | ---- | 顶部评论列表(结构和评论列表相同) | * 示例用法 ```json { "name": "comic", "type": "comic", "style": { "navigationTitle": "漫画详情", "enableLoadmore": 1, "componentBackgroundOpacity": 0.7 }, "detail": { "request": { "url": "/manhua/detail/{{id}}/", "device": "电脑" }, "dynamicData": { "title": "@sel:class.detail-info-title[0]>>text", "cover": "@sel:class.detail-info-cover[0]>>tag.img[0]>>attr.src", "subtitle": "@sel:class.cy_xinxi[0]>>tex", "description": "@sel:id.comic-description>>text", "tags": { "list": "@sel:class.cy_xinxixi[0]>>tag.a", "title": "@sel:text", "url": "tag?str=@sel:attr.href@replace:https://www.dongman.la" } } }, "items": { "request": { "url": "/manhua/detail/{{id}}/", "device": "电脑" }, "dynamicData": { "list": "@sel:id.mh-chapter-list-ol-0>>tag.li@reverse:", "title": "@sel:tag.a[0]>>text", "href": "@sel:tag.a[0]>>attr.href" } }, "context": { "request": { "url": "{{href}}all.html", "device": "电脑" }, "dynamicData": { "content": "@sel:class.imgListBox[0]>>tag.img>>attr.data-src" } }, "components": [{ "name": "card", "style": { "cardTitle": "可能感兴趣的", "cellName": "v-cell", "cellImageHeight": 300, "cellColumn": 3, "enableRefresh": 1 }, "request": { "url": "/manhua/detail/{{id}}/", "device": "电脑" }, "dynamicData": { "list": "@sel:id.similarList>>tag.li", "title": "@sel:tag.b[0]>>text", "cover": "@sel:tag.img[0]>>attr.src", "url": "comic?id=@sel:tag.a[0]>>attr.href@match:detail&es;/>>&es;/>>1" } }] } ``` #video(视频页) * 注意事项 - 每个属性(例如:detail和items)中都默认包含staticData,request和dynamicData属性,这里因为内容太多就不显示了 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | detail | Object | ---- | ---- | 详情信息 | | items | Object | ---- | ---- | 剧集列表 | | context | Object | ---- | ---- | 剧集正文 | | barrages | Object | ---- | ---- | 弹幕列表 | | comments | Object | ---- | ---- | 评论列表 | | components | Array | ---- | ---- | 组件列表(详情见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(详情见下方cell单元格讲解) | * detail(详情信息) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面图片网络路径 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | tags | Object | ---- | ---- | 标签列表 | | isAdult | Number | 0 | 1/0 | 是否敏感内容 | * tags(标签列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * items(剧集列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | Array | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面 | | src | String | ---- | ---- | 播放链接 | | ...(这里可以任意添加属性) | Any | ---- | ---- | 自定义属性(用于请求正文内容时使用,你可以自定义为任何内容) | * context(剧集正文) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面 | | src | String | ---- | ---- | 播放链接 | * comments(评论列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | avatar | String | ---- | ---- | 头像网络图片路径 | | title | String | ---- | ---- | 评论标题 | | subtitle | String | ---- | ---- | 评论二级标题 | | content | String | ---- | ---- | 评论内容 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | | subComments | Object | ---- | ---- | 二级评论列表(结构和评论列表相同) | | masterComments | Object | ---- | ---- | 顶部评论列表(结构和评论列表相同) | * barrages(弹幕列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | text | String | ---- | ---- | 弹幕 | | time | Number | ---- | ---- | 弹幕显示时间(单位s) | | color | String | ---- | ---- | 弹幕颜色 | * 示例用法 ```json { "name": "video", "type": "video", "style": { "navigationTitle": "视频详情", "enableLoadmore": 1, "enableNavigationTransparent": 1 }, "detail": { "request": { "url": "/index.php/vod/detail/id/{{id}}.html", "device": "电脑" }, "dynamicData": { "title": "@sel:class.page-title[0]>>text", "cover": "@sel:class.video-cover[0]>>tag.img[0]>>attr.data-src", "description": "@sel:class.video-info-main[0]>>text", "tags": { "list": "@sel:class.video-info-aux[0]>>tag.a", "title": "@sel:text", "url": "tag?href=@sel:attr.href&navigationTitle=@sel:text" } } }, "items": { "request": { "url": "/index.php/vod/detail/id/{{id}}.html", "device": "电脑" }, "dynamicData": { "list": "@sel:id.sort-item-2>>tag.a", "title": "@sel:text", "requestHref": "@sel:attr.href" } }, "context": { "request": { "url": "{{requestHref}}", "device": "电脑" }, "dynamicData": { "src": "@sel:class.player-wrapper[0]>>tag.script[0]>>content@replace:var player_aaaa=@sync:return JSON.parse(lastResult)@json:url", "formats": "m3u8" } }, "comments": { "request": { "url": "/index.php/comment/ajax.html?rid={{id}}&mid=1&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.mxone-comment__item", "title": "@sel:class.title[0]>>text", "avatar": "@sel:class.face[0]>>attr.src@sync:return lastResult.indexOf('http') == -1 ? 'http://www.lzizy9.com/' + lastResult : lastResult", "subtitle": "@sel:class.text-muted@sync:return lastResult[1].innerHTML.trim() + ' ' + lastResult[0].innerHTML.trim()", "content": "@sel:class.comment-cont[0]>>text" } }, "barrages": { "request": { "url": "{{requestHref}}", "device": "电脑" }, "dynamicData": { "list": "@json:data.list", "text": "@json:title", "time": "@sel:time", "color": "@sel:color" } }, "components": [{ "name": "card", "style": { "cardTitle": "相关影片", "cellName": "v-cell", "cellColumn": 3 }, "request": { "url": "/index.php/vod/detail/id/{{id}}.html", "device": "电脑" }, "dynamicData": { "list": "@sel:class.module-items[0]>>class.module-item", "title": "@sel:class.module-item-title[0]>>text", "cover": "@sel:tag.img[0]>>attr.data-src", "subtitle": "@sel:class.module-item-text[0]>>text", "url": "video?id=@sel:class.module-item-title[0]>>attr.href@match:id&es;/>>.html>>1" } }] } ``` #audio(音频页) * 注意事项 - 每个属性(例如:detail和items)中都默认包含staticData,request和dynamicData属性,这里因为内容太多就不显示了 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | detail | Object | ---- | ---- | 详情信息 | | items | Object | ---- | ---- | 播放列表 | | context | Object | ---- | ---- | 音频正文 | | lyrics | Object | ---- | ---- | 歌词列表 | | comments | Object | ---- | ---- | 评论列表 | | components | Array | ---- | ---- | 组件列表(详情见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(详情见下方cell单元格讲解) | * detail(详情信息) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面图片网络路径 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | content | String | ---- | ---- | 文本内容 | | tags | Object | ---- | ---- | 标签列表 | | isAdult | Number | 0 | 1/0 | 是否敏感内容 | * tags(标签列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * items(播放列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | Array | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面 | | src | String | ---- | ---- | 播放链接 | | referer | String | ---- | ---- | 播放链接源域名(用于处理防盗链) | | ...(这里可以任意添加属性) | Any | ---- | ---- | 自定义属性(用于请求正文内容时使用,你可以自定义为任何内容) | * context(音频正文) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面 | | src | String | ---- | ---- | 播放链接 | | referer | String | ---- | ---- | 播放链接源域名(用于处理防盗链) | * comments(评论列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | avatar | String | ---- | ---- | 头像网络图片路径 | | title | String | ---- | ---- | 评论标题 | | subtitle | String | ---- | ---- | 评论二级标题 | | content | String | ---- | ---- | 评论内容 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | | subComments | Object | ---- | ---- | 二级评论列表(结构和评论列表相同) | | masterComments | Object | ---- | ---- | 顶部评论列表(结构和评论列表相同) | * lyrics(歌词列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 歌词 | | time | Number | ---- | ---- | 歌词显示时间 | * 示例用法 ```json { "name": "music", "type": "audio", "style": { "navigationTitle": "音乐详情", "componentBackgroundOpacity": 0.5 }, "detail": { "request": { "url": "/listen/{{id}}", "device": "电脑" }, "dynamicData": { "title": "@sel:class.frame1[0]>>tag.h1[0]>>text", "subtitle": "@sel:class.song_info[0]>>text", "cover": "@sel:class.music_intro[0]>>tag.img[0]>>attr.src@sync:return lastResult && lastResult.indexOf('http') == -1 ? 'https://www.itingwa.com' + lastResult : lastResult", "content": "@sel:class.music_intro[0]>>content@replaceAll:src="&es;/file>>src="https://www.itingwa.com/file" } }, "items": { "request": { "url": "/listen/{{id}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.jp-jplayer", "href": "@sel:attr.init-data" } }, "context": { "request": { "url": "{{href}}", "device": "电脑" }, "dynamicData": { "src": "@sel:attr.init-data" } }, "lyrics": { "request": { "url": "{{href}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.jp-lyrics", "title": "@sel:text", "time": "@sel:attr.init-date" } }, "comments": { "request": { "url": "?c=comment&m=get_comment&id={{id}}&type=0&p={{page}}" }, "dynamicData": { "list": "@json:comments.list", "title": "@json:u_name", "subtitle": "@json:comm_addtime", "avatar": "https://www.itingwa.com/upload/pic/180/@json:u_img", "content": "@json:content", "url": "user?id=@json:comm_user" } }, "components": [{ "name": "card", "style": { "cardTitle": "发布者", "cellName": "h-cell", "cellColumn": 1, "cellImageWidth": 90, "cellImageHeight": 90 }, "request": { "url": "/listen/{{id}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.rt_frame", "title": "@sel:class.clearfix[0]>>class.nickname[0]>>text", "subtitle": "@sel:class.user_data[0]>>text", "cover": "@sel:class.clearfix[0]>>tag.img[0]>>attr.src", "url": "user?id=@sel:class.clearfix[0]>>tag.a[0]>>attr.href@split:u/>>1" } },{ "name": "card", "style": { "cardTitle": "相关专辑", "cellName": "v-cell", "cellColumn": 3, "cellImageHeight": 200 }, "request": { "url": "/listen/{{id}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.album_items[0]>>tag.li", "title": "@sel:class.top_10[0]>>text", "cover": "@sel:tag.img[0]>>attr.src", "url": "album?id=@sel:tag.a[0]>>attr.href@split:album/>>1&background=@sel:tag.img[0]>>attr.src" } }] } ``` #picture(图片页) * 注意事项 - 每个属性(例如:detail和items)中都默认包含staticData,request和dynamicData属性,这里因为内容太多就不显示了 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | detail | Object | ---- | ---- | 详情信息 | | items | Object | ---- | ---- | 图片列表 | | context | Object | ---- | ---- | 图片正文 | | comments | Object | ---- | ---- | 评论列表 | | components | Array | ---- | ---- | 组件列表(详情见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(详情见下方cell单元格讲解) | * detail(详情信息) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面图片网络路径 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | tags | Object | ---- | ---- | 标签列表 | | isAdult | Number | 0 | 1/0 | 是否敏感内容 | * tags(标签列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * items(图片列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面 | | src | String | ---- | ---- | 图片链接 | | referer | String | ---- | ---- | 图片源 | | decrypt | String | ---- | ---- | 图片解密 | | ...(这里可以任意添加属性) | Any | ---- | ---- | 自定义属性(用于请求正文内容时使用,你可以自定义为任何内容) | * context(图片正文) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面 | | src | String | ---- | ---- | 图片链接 | | referer | String | ---- | ---- | 图片源 | | decrypt | String | ---- | ---- | 图片解密 | * comments(评论列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | avatar | String | ---- | ---- | 头像网络图片路径 | | title | String | ---- | ---- | 评论标题 | | subtitle | String | ---- | ---- | 评论二级标题 | | content | String | ---- | ---- | 评论内容 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | | subComments | Object | ---- | ---- | 二级评论列表(结构和评论列表相同) | | masterComments | Object | ---- | ---- | 顶部评论列表(结构和评论列表相同) | * 示例用法 ```json { "name": "picture", "type": "picture", "style": { "navigationTitle": "壁纸详情", "enableNavigationTransparent": 1 }, "detail": { "staticData": { "cover": "{{background}}" }, "request": { "url": "{{href}}", "device": "手机" }, "dynamicData": { "title": "@sel:class.detail-title[0]>>text", "subtitle": "@sel:class.detail-info[0]>>text" } }, "items": { "request": { "url": "{{href}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.image-content[0]>>class.swiper-slide", "title": "@sel:tag.img[0]>>attr.alt", "cover": "https:@sel:tag.img[0]>>attr.data-src", "src": "https:@sel:tag.img[0]>>attr.data-src" } }, "comments": { "request": { "url": "?c=comment&m=get_comment&id={{id}}&type=0&p={{page}}" }, "dynamicData": { "list": "@json:comments.list", "title": "@json:u_name", "subtitle": "@json:comm_addtime", "avatar": "https://www.itingwa.com/upload/pic/180/@json:u_img", "content": "@json:content", "url": "user?id=@json:comm_user" } }, "components": [{ "name": "card", "style": { "cardTitle": "相关推荐", "cellName": "v-cell", "cellColumn": 2, "cellImageHeight": 500 }, "request": { "url": "{{href}}", "device": "手机" }, "dynamicData": { "list": "@sel:class.list-ul[0]>>class.list-li", "title": "@sel:class.li-title[0]>>text", "cover": "https:@sel:tag.img[0]>>attr.data-src", "url": "picture?href=@sel:tag.a[0]>>attr.href&background=https:@sel:tag.img[0]>>attr.data-src" } }] } ``` #live(直播页) * 注意事项 - 每个属性(例如:detail)中都默认包含staticData,request和dynamicData属性,这里因为内容太多就不显示了 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | detail | Object | ---- | ---- | 详情信息 | | items | Object | ---- | ---- | 直播列表 | | context | Object | ---- | ---- | 正文内容 | | components | Array | ---- | ---- | 组件列表(详情见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(详情见下方cell单元格讲解) | * detail(详情信息) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面图片网络路径 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | tags | Object | ---- | ---- | 标签列表 | | isLive | Number | 1 | 1/0 | 是否直播 | | isAdult | Number | 0 | 1/0 | 是否敏感内容 | * items(直播列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面 | | src | String | ---- | ---- | 播放链接 | | isLive | Number | 1 | 1/0 | 是否直播 | | type | String | auto | auto/hls/flv | 解码器类型 | | ...(这里可以任意添加属性) | Any | ---- | ---- | 自定义属性(用于请求正文内容时使用,你可以自定义为任何内容) | * context(正文内容) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面 | | src | String | ---- | ---- | 播放链接 | | isLive | Number | 1 | 1/0 | 是否直播 | | type | String | auto | auto/hls/flv | 解码器类型 | * tags(标签列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "name": "live", "type": "live", "style": { "navigationTitle": "直播详情", "enableNavigationTransparent": 1 }, "detail": { "request": { "url": "/live/detail/{{id}}", "device": "电脑" }, "dynamicData": { "title": "@sel:class.vod>>attr.alt", "cover": "@sel:class.cover>>attr.src" } }, "items": { "request": { "url": "/live/detail/{{id}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.vod>>class.vod_list", "title": "@sel:class.title>>text", "playId": "@sel:class.player>>attr.href" } }, "context": { "request": { "url": "/live/player/{{playId}}", "device": "电脑" }, "dynamicData": { "src": "@sel:tag.video>>attr.src" } } } ``` #article(文章页) * 注意事项 - 每个属性(例如:detail)中都默认包含staticData,request和dynamicData属性,这里因为内容太多就不显示了 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | detail | Object | ---- | ---- | 详情信息 | | items | Object | ---- | ---- | 更多列表 | | comments | Object | ---- | ---- | 评论列表 | | components | Array | ---- | ---- | 组件列表(详情见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(详情见下方cell单元格讲解) | * detail(详情信息) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 封面图片网络路径 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | content | String | ---- | ---- | 文章内容 | | tags | Object | ---- | ---- | 标签列表 | | images | Array | ---- | ---- | 图片列表 | | video | Object | ---- | ---- | 视频信息 | | isAdult | Number | 0 | 1/0 | 是否敏感内容 | * items(更多列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | avatar | String | ---- | ---- | 偷笑 | | subtitle | String | ---- | ---- | 二级标题 | | content | String | ---- | ---- | 文章内容 | | url | String | ---- | ---- | 跳转链接 | * tags(标签列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * comments(评论列表) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | avatar | String | ---- | ---- | 头像网络图片路径 | | title | String | ---- | ---- | 评论标题 | | subtitle | String | ---- | ---- | 评论二级标题 | | content | String | ---- | ---- | 评论内容 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | | subComments | Object | ---- | ---- | 二级评论列表(结构和评论列表相同) | | masterComments | Object | ---- | ---- | 顶部评论列表(结构和评论列表相同) | * 示例用法 ```json { "name": "article", "type": "article", "style": { "navigationTitle": "文章详情", "componentBorderRadius": 10, "coverWidth": 80, "coverHeight": 80, "enableLoadmore": 1 }, "detail": { "request": { "url": "/t.php?id={{id}}&page=1", "device": "电脑" }, "dynamicData": { "title": "@sel:class.topic-user[0]>>tag.strong[0]>>text", "cover": "@sel:class.topic-user>>class.avatar[0]>>attr.src@sync:return baseUrl + '/' + lastResult", "subtitle": "@sel:class.o_header[0]>>text", "content": "@sel:class.topic-picture[0]@sel:class.topic-message[0]>>content&&class.topic-picture[0]>>content&&class.append-items[0]>>content@join:&wrap;@sync:return lastResult.replace(/.&es;/picture/g, baseUrl + '/picture')@replaceAll:_s>>_b@sel:class.topic-message[0]>>content&&class.append-items[0]>>content@join:&wrap;" } }, "items": { "request": { "url": "/t.php?id={{id}}&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.reply-items[0]>>class.reply-item", "title": "@sel:class.item-nickname[0]>>text", "avatar": "@sel:class.item-avatar[0]>>attr.src@sync:return baseUrl + '/' + lastResult", "subtitle": "@sel:class.time[0]>>text", "content": "@sel:class.item-picture[0]@sel:class.item-message[0]>>content&&class.item-picture[0]>>content@join:&wrap;@sync:return lastResult.replace(/.&es;/picture/g, baseUrl + '/picture')@replaceAll:_s>>_b@sel:class.item-message[0]>>content" } }, "components": [{ "name": "title", "style": { "title": "全部回复" } }], "cell": { "style": { "cellName": "t-cell", "cellColumn": 1 }, "request": { "url": "/t.php?id={{id}}&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.reply-items[0]>>class.reply-item", "title": "@sel:class.item-nickname[0]>>text", "avatar": "@sel:class.item-avatar[0]>>attr.src@sync:return baseUrl + '/' + lastResult", "subtitle": "@sel:class.time[0]>>text", "description": "@sel:class.item-message[0]>>text", "images": "@sel:class.item-picture[0]>>tag.img>>attr.data-expand@map:item.replace(/.&es;/picture/g, baseUrl + '/picture')" } } } ``` #user(用户页) * 注意事项 - detail包含staticData,request和dynamicData属性,这里因为内容太多就不显示了 - subsection为集合,同column页面类似 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | detail | Object | ---- | ---- | 详情信息 | | subsection | Array | ---- | ---- | 分栏列表 | * detail(详情信息) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | avatar | String | ---- | ---- | 头像图片网络路径 | | cover | String | ---- | ---- | 封面图片网络路径 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | isAdult | Number | 0 | 1/0 | 是否敏感 | * subsection | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :---- | :----: | :----: | :----: | :---- | | label | String | ---- | ---- | 分栏标题 | | components | Array | ---- | ---- | 组件集合(具体见下方components组件讲解) | | cell | Object | ---- | ---- | 单元格列表(具体见下方cell单元格讲解) | * 示例用法 ```json { "name": "user", "type": "user", "style": { "navigationTitle": "作者信息", "enableNavigationTransparent": 1, "enableSwiper": 1, "background": "#ffffff", "subsectionColumn": 3 }, "darkStyle": { "background": "#131313" }, "detail": { "request": { "url": "/user/info?id={{id}}", "device": "电脑" }, "dynamicData": { "title": "@sel:class.r-side[0]>>class.name[0]>>tag.p[0]>>text", "avatar": "@sel:class.r-side[0]>>class.profile-cover[0]>>tag.img[0]>>attr.src", "cover": "https://eli.linovel.net/static/img/profile_cover.22b302b.jpg", "description": "@sel:class.r-side[0]>>class.profile[0]>>class.list[0]>>text" } }, "subsection": [{ "label": "小说", "cell": { "style": { "cellName": "v-cell", "cellColumn": 3, "cellImageHeight": 300 }, "request": { "url": "/user/info?id={{id}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.works-grid[0]>>class.grid", "title": "@sel:class.title[0]>>text", "cover": "@sel:tag.img[0]>>attr.src", "url": "book?id=@sel:tag.a[0]>>attr.href@match:book&es;/>>.html>>1" } } },{ "label": "粉丝", "style": { "enableLoadmore": 1 }, "cell": { "style": { "cellName": "h-cell", "cellColumn": 1, "cellImageWidth": 80, "cellImageHeight": 80, "cellImageBorderRadius": 80 }, "request": { "url": "/user/followerList?id={{id}}&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.user-list[0]>>tag.li", "title": "@sel:class.name[0]>>text", "subtitle": "@sel:class.sign[0]>>text", "cover": "@sel:tag.img[0]>>attr.data-original", "url": "user?id=@sel:tag.a[0]>>attr.href@replace:/user/info?id=" } } },{ "label": "关注", "style": { "enableLoadmore": 1 }, "cell": { "style": { "cellName": "h-cell", "cellColumn": 1, "cellImageWidth": 80, "cellImageHeight": 80, "cellImageBorderRadius": 80 }, "request": { "url": "/user/followeeList?id={{id}}&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.user-list[0]>>tag.li", "title": "@sel:class.name[0]>>text", "subtitle": "@sel:class.sign[0]>>text", "cover": "@sel:tag.img[0]>>attr.data-original", "url": "user?id=@sel:tag.a[0]>>attr.href@replace:/user/info?id=" } } }] } ``` #cell(单元格) * h-cell(横向单元格) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cellName | String | h-cell | ---- | 单元格名称 | | cellColumn | Number | 3 | ---- | 列数 | | cellGap | Number | 30 | ---- | 间距 | | cellImageWidth | Number | 120 | ---- | 图片宽度 | | cellImageHeight | Number | 160 | ---- | 图片高度 | | cellImageBorderRadius | Number | 10 | ---- | 图片圆角 | | cellImageTipSize | Number | 20 | ---- | 图片加载提示文字大小 | | cellTitleLines | Number | 1 | ---- | 标题最多显示多少行 | | cellDescriptionLines | Number | 3 | ---- | 简介最多显示多少行 | | enableOrder | Number | 0 | 0/1 | 显示列表序号 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | cover | String | ---- | ---- | 图片地址 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "cell": { "style": { "cellName": "h-cell", "cellImageWidth": 160, "cellImageHeight": 220, "cellDescriptionLines": 4 }, "request": { "url": "/search/?kw={{keyword}}&sign={{$2}}&sort={{$1}}&words=-1&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.rank-book-list[0]>>tag.a", "title": "@sel:class.book-name[0]>>text", "cover": "@sel:class.book-cover[0]>>tag.img[0]>>attr.src", "subtitle": "@sel:class.book-extra[0]>>text", "description": "@sel:class.book-intro[0]>>text", "url": "book?id=@sel:attr.href@match:book&es;/>>.html>>1" } } } ``` * v-cell(竖向单元格) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cellName | String | v-cell | ---- | 单元格名称 | | cellColumn | Number | 3 | ---- | 列数 | | cellGap | Number | 30 | ---- | 间距 | | cellImageHeight | Number | 240 | ---- | 图片高度 | | cellImageBorderRadius | Number | 10 | ---- | 图片圆角 | | cellImageTipSize | Number | 20 | ---- | 图片加载提示文字大小 | | cellTitleLines | Number | 1 | ---- | 标题最多显示多少行 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | subtitle | String | ---- | ---- | 二级标题 | | cover | String | ---- | ---- | 图片地址 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "cell": { "style": { "cellName": "v-cell", "cellImageHeight": 240, "cellColumn": 3, }, "request": { "url": "/search/?kw={{keyword}}&sign={{$2}}&sort={{$1}}&words=-1&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.rank-book-list[0]>>tag.a", "title": "@sel:class.book-name[0]>>text", "cover": "@sel:class.book-cover[0]>>tag.img[0]>>attr.src", "subtitle": "@sel:class.book-extra[0]>>text", "url": "book?id=@sel:attr.href@match:book&es;/>>.html>>1" } } } ``` * img-cell(图片单元格) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cellName | String | img-cell | ---- | 单元格名称 | | cellColumn | Number | 3 | ---- | 列数 | | cellGap | Number | 30 | ---- | 间距 | | cellImageHeight | Number | 240 | ---- | 图片高度 | | cellImageBorderRadius | Number | 10 | ---- | 图片圆角 | | cellImageTipSize | Number | 20 | ---- | 图片加载提示文字大小 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | cover | String | ---- | ---- | 图片地址 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "cell": { "style": { "cellName": "img-cell", "cellImageHeight": 240, "cellColumn": 3, }, "request": { "url": "/search/?kw={{keyword}}&sign={{$2}}&sort={{$1}}&words=-1&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.rank-book-list[0]>>tag.a", "cover": "@sel:class.book-cover[0]>>tag.img[0]>>attr.src", "url": "book?id=@sel:attr.href@match:book&es;/>>.html>>1" } } } ``` * text-cell(文字单元格) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cellName | String | text-cell | ---- | 单元格名称 | | cellColumn | Number | 3 | ---- | 列数 | | cellGap | Number | 30 | ---- | 间距 | | cellTitleLines | Number | 1 | ---- | 标题最多显示多少行 | | cellDescriptionLines | Number | 3 | ---- | 简介最多显示多少行 | | enableOrder | Number | 0 | 0/1 | 显示列表序号 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | subtitle | String | ---- | ---- | 二级标题 | | subtext | String | ---- | ---- | 底部文本 | | description | String | ---- | ---- | 简介 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "cell": { "style": { "cellName": "text-cell", "cellImageHeight": 240, "cellColumn": 3, }, "request": { "url": "/search/?kw={{keyword}}&sign={{$2}}&sort={{$1}}&words=-1&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.rank-book-list[0]>>tag.a", "title": "@sel:class.book-name[0]>>text", "subtitle": "@sel:class.book-extra[0]>>text", "url": "book?id=@sel:attr.href@match:book&es;/>>.html>>1" } } } ``` * tag-cell(标签单元格) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cellName | String | tag-cell | ---- | 单元格名称 | | cellColumn | Number/String | auto | ---- | 列数 | | cellGap | Number | 30 | ---- | 间距 | | cellTitleLines | Number | 1 | ---- | 标题最多显示多少行 | | cellTitleSize | Number | 24 | ---- | 标签文字大小 | | cellBorderRadius | Number | 10 | ---- | 标签圆角 | | cellBackgroundColor | Number | 10 | ---- | 标签背景色(开启镂空时为主体色) | | enablePlain | Number | 0 | 1/0 | 开启镂空效果 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "components": [ { "name": "card", "style": { "cardTitle": "热门标签",//卡片标题 "cellName": "tag-cell", "cellColumn": "auto", }, "request": { "url": "/search/?kw={{keyword}}&sign={{$2}}&sort={{$1}}&words=-1", "device": "电脑" },//请求 "dynamicData": { "list": "@sel:class.rank-book-list[0]>>tag.a", "title": "@sel:class.book-name[0]>>text", "url": "book?id=@sel:attr.href@match:book&es;/>>.html>>1" }//动态数据 } ] } ``` * a-cell(文章单元格) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cellName | String | a-cell | ---- | 单元格名称 | | cellColumn | Number | 1 | ---- | 列数 | | cellGap | Number | 30 | ---- | 间距 | | cellImageWidth | Number | 230 | ---- | 图片宽度 | | cellImageHeight | Number | 190 | ---- | 图片高度 | | cellTitleLines | Number | 1 | ---- | 标题最多显示几行 | | cellDescriptionLines | Number | 3 | ---- | 简介最多显示几行 | | cellImageTipSize | Number | 1 | ---- | 图片加载提示文字大小 | | cellImageBorderRadius | Number | 10 | ---- | 图片圆角 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | subtitle | String | ---- | ---- | 二级标题 | | description | String | ---- | ---- | 简介 | | images | Array/String | ---- | ---- | 图片组 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "cell": { "style": { "cellName": "a-cell" }, "request": { "url": "?c=tingshuo&m=get_feeds", "device": "电脑" }, "dynamicData": { "list": "@json:data@sel:tag.dl", "title": "@sel:class.feed_detail[0]>>class.hide[0]>>text", "description": "@sel:class.feed_info[0]>>tag.div[0]&&tag.div[1]>>text@string:", "subtitle": "@sel:class.feed_info[0]>>tag.ul[0]>>text", "images": "https://www.itingwa.com@sel:class.feed_img[0]>>attr.src", "url": "@sel:tag.a[1]>>attr.href@have:listenmusic?id=@sel:tag.a[1]>>attr.href@split:listen/>>1@sel:tag.a[1]>>attr.href@have:albumalbum?id=@sel:tag.a[1]>>attr.href@split:album/>>1article?id=@sel:tag.a[1]>>attr.href@split:article/>>1&background=https://www.itingwa.com@sel:class.feed_img[0]>>attr.src", "dataId": "@sel:attr.init-data" } } } ``` * c-cell(评论单元格) * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | subtitle | String | ---- | ---- | 二级标题 | | avatar | String | ---- | ---- | 头像 | | content | String | ---- | ---- | 评论内容 | | masterComments | Array | ---- | ---- | 顶部评论集合 | | subComments | Array | ---- | ---- | 二级评论集合 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "comments": { "request": { "url": "?c=comment&m=get_comment&id={{id}}&type=0&p={{page}}" }, "dynamicData": { "list": "@json:items", "avatar": "@json:author.avatar", "title": "@json:author.nick", "subtitle": "@json:date@sync:return lastResult*1000@dateFormat:", "content": "@json:content", "url": "user?id=@json:author.id", "subComments": { "list": "@json:replies.items", "avatar": "@json:author.avatar", "title": "@json:author.nick", "subtitle": "@json:date@sync:return lastResult*1000@dateFormat:", "content": "@json:content", "url": "user?id=@json:author.id" } } } } ``` * w-cell(瀑布流单元格) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cellName | String | w-cell | ---- | 单元格名称 | | cellColumn | Number | 3 | ---- | 列数 | | cellGap | Number | 30 | ---- | 间距 | | cellImageHeight | Number | 240 | ---- | 图片高度 | | cellImageBorderRadius | Number | 10 | ---- | 图片圆角 | | cellImageTipSize | Number | 20 | ---- | 图片加载提示文字大小 | | cellTitleLines | Number | 1 | ---- | 标题最多显示多少行 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | subtitle | String | ---- | ---- | 二级标题 | | cover | String | ---- | ---- | 图片地址 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "cell": { "style": { "cellName": "w-cell", "cellImageHeight": 240, "cellColumn": 3, }, "request": { "url": "/search/?kw={{keyword}}&sign={{$2}}&sort={{$1}}&words=-1&page={{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.rank-book-list[0]>>tag.a", "title": "@sel:class.book-name[0]>>text", "cover": "@sel:class.book-cover[0]>>tag.img[0]>>attr.src", "subtitle": "@sel:class.book-extra[0]>>text", "url": "book?id=@sel:attr.href@match:book&es;/>>.html>>1" } } } ``` * t-cell(讨论/帖子 单元格) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cellName | String | t-cell | ---- | 单元格名称 | | cellColumn | Number | 3 | ---- | 列数 | | cellGap | Number | 30 | ---- | 间距 | | cellImageColumn | Number | 3 | ---- | 图片组列数 | | cellImageHeight | Number | 160 | ---- | 图片组单个图片高度 | | cellImageBorderRadius | Number | 10 | ---- | 图片组单个图片圆角 | | cellImageTipSize | Number | 20 | ---- | 图片加载提示文字大小 | | cellTitleLines | Number | 1 | ---- | 标题最多显示多少行 | | cellDescriptionLines | Number | 3 | ---- | 简介最多显示多少行 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | subtitle | String | ---- | ---- | 二级标题 | | subtext | String | ---- | ---- | 底部文本 | | avatar | String | ---- | ---- | 头像 | | description | String | ---- | ---- | 简介 | | images | Array | ---- | ---- | 图片组 | | video | Object | ---- | ---- | 视频信息 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * video(视频对象) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 视频标题 | | cover | String | ---- | ---- | 视频封面 | | src | String | ---- | ---- | 视频播放连接 | * 示例用法 ```json { "cell": { "style": { "cellName": "t-cell", "cellColumn": 1 }, "request": { "device": "手机" }, "dynamicData": { "list": "@json:data.list", "title": "@json:author", "subtitle": "@json:ghType@equal:haokan官方账号@json:authorWishes", "subtext": "@json:ghType@equal:haokan@json:playcntText | @json:durationText", "avatar": "@json:authorIcon", "description": "#@json:videoInfo.title", "video": { "title": "@json:videoInfo.title", "cover": "@json:videoInfo.poster", "src": "@json:videoInfo.clarityUrl[0].url" }, "url": "video?id=@json:vid" } } } ``` #components(组件) * title(标题组件) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题名称 | | color | String | #333333 | ---- | 标题颜色 | * 示例用法 ```json { "components": [ { "name": "title", "style": { "title": "为您推荐",//标题名称 "color": "#ffffff"//标题颜色 } } ] } ``` * search-input(搜索框) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | | placeholder | String | ---- | ---- | 搜索框提示文字 | | borderRadius | Number | 10 | ---- | 搜索框圆角 | | enableSearch | Number | 1 | 1/0 | 开启输入搜索功能 | * 示例用法 ```json { "components": [ { "name": "search-input", "style": { "url": "search",//跳转name为search的规则页面 "placeholder": "点击搜索内容",//提示文字 "borderRadius": 10,//圆角 "enableSearch": 1//开启搜索 } }, { "name": "search-input", "style": { "url": "https://www.baidu.com"//跳转在线网址 } } ] } ``` * slider(轮播图) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | height | Number | 280 | ---- | 高度 | | enableIndicatorDots | Number | 1 | 1/0 | 开启指示点 | | indicatorActiveColor | String | ---- | ---- | 指示点选中色 | | titleShow | Number | 1 | 1/0 | 展示轮播图标题 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 轮播图标题 | | cover | String | ---- | ---- | 轮播图图片路径 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "components": [ { "name": "slider", "style": { "height": 280,//高度 "enableIndicatorDots": 1,//开启指示点 "indicatorActiveColor": "#42b983",//指示点选中色 "titleShow": 1//展示标题 }, "staticData": [{ "title": "轮播图第一张",//标题 "cover": "https://image.test.com/test1.png",//图片路径 "url": "https://www.test.com"//跳转路径 },{ "title": "轮播图第二张",//标题 "cover": "https://image.test.com/test2.png",//图片路径 "url": "https://www.test.com"//跳转路径 }]//静态数据 }, { "name": "slider", "style": { "height": 280,//高度 "enableIndicatorDots": 1,//开启指示点 "indicatorActiveColor": "#42b983",//指示点选中色 "titleShow": 0//不展示标题 }, "request": { "url": "https://www.test.com",//请求链接 "device": "电脑"//请求平台 },//请求 "dynamicData": { "list": "@sel:tag.li",//列表规则 "cover": "@sel:class.img[0]>>attr.src",//图片规则 "url": "detail?id=@sel:class.link[0]>>attr.href"//跳转路径规则 }//动态数据 } ] } ``` * banner(banner图) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | height | Number | ---- | ---- | 高度 | | borderRadius | Number | 15 | ---- | 圆角 | | mode | String | widthFix | widthFix/aspectFit/aspectFill/heightFix | 图片剪切模式 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cover | String | ---- | ---- | 轮播图图片路径 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "components": [ { "name": "banner", "style": { "height": 280,//高度 "borderRadius": 15,//开启指示点 "mode": "aspectFill",//图片剪切模式 }, "staticData": { "cover": "https://image.test.com/test1.png",//图片路径 "url": "https://www.test.com"//跳转路径 }//静态数据 }, { "name": "banner", "style": { "height": 280,//高度 "borderRadius": 15,//圆角 "mode": "aspectFill",//图片剪切模式 }, "request": { "url": "https://www.test.com",//请求链接 "device": "电脑"//请求平台 },//请求 "dynamicData": { "cover": "@sel:class.img[0]>>attr.src",//图片规则 "url": "detail?id=@sel:class.link[0]>>attr.href"//跳转路径规则 }//动态数据 } ] } ``` * notice-bar(公告栏) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | icon | String | ---- | ---- | 图标 可使用网络图片路径或者[图标库](https://www.iconfont.cn/collections/detail?cid=33) | | borderRadius | Number | 10 | ---- | 圆角 | | moreText | String | ---- | ---- | 更多按钮文字 | | moreUrl | String | ---- | ---- | 更多跳转路径(支持在线网址和规则页面) | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "components": [ { "name": "notice-bar", "style": { "icon": "notification",//图标 可使用网络图片路径 "moreText": "全部",//更多按钮文字 "moreUrl": "notice",//更多跳转路径(网址 | 页面) "borderRadius": 10,//圆角 }, "staticData": [{ "title": "这是一条公告1",//标题 "url": "https://www.test.com"//跳转路径 },{ "cover": "这是一条公告2",//标题 "url": "https://www.test.com"//跳转路径 }]//静态数据 }, { "name": "notice-bar", "style": { "icon": "notification",//图标 可使用网络图片路径 "moreText": "全部",//更多按钮文字 "moreUrl": "notice",//更多跳转路径(网址 | 页面) "borderRadius": 10,//圆角 }, "request": { "url": "https://www.test.com",//请求链接 "device": "电脑"//请求平台 },//请求 "dynamicData": { "list": "@sel:tag.li",//列表规则 "title": "@sel:tag.p[0]>>text",//标题规则 "url": "detail?id=@sel:class.link[0]>>attr.href"//跳转路径规则 }//动态数据 } ] } ``` * menu(菜单栏) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | column | Number | 4 | ---- | 列数 | | columnGap | Number | 15 | ---- | 间隔 | | borderRadius | Number | 15 | ---- | 圆角 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | icon | String | ---- | ---- | 图标 可使用网络图片路径或者[图标库](https://www.iconfont.cn/collections/detail?cid=33) | | iconColor | String | ---- | ---- | 图标颜色 | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "components": [ { "name": "menu", "style": { "column": 2,//列数 "columnGap": 15,//列间隔 "borderRadius": 15//圆角 }, "staticData": [{ "icon": "notifacation",//图标 可使用网络图片路径 "iconColor": "#f5f5f5",//图标颜色 "title": "菜单",//标题 "url": "list"//跳转路径(网址 | 页面) },{ "icon": "notifacation",//图标 可使用网络图片路径 "iconColor": "#f5f5f5",//图标颜色 "title": "菜单",//标题 "url": "list"//跳转路径(网址 | 页面) }]//静态数据 }, { "name": "menu", "style": { "column": 2,//列数 "columnGap": 15,//列间隔 "borderRadius": 15//圆角 }, "request": { "url": "https://www.test.com",//请求链接 "device": "电脑"//请求平台 },//请求 "dynamicData": { "list": "@sel:tag.li",//列表规则 "icon": "@sel:tag.img[0]>>attr.src",//图片规则 "title": "@sel:tag.p[0]>>text",//标题规则 "url": "detail?id=@sel:class.link[0]>>attr.href"//跳转路径(网址 | 页面) }//动态数据 } ] } ``` * link(链接) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | iconColor | String | ---- | ---- | 图标颜色 | | iconBorderRadius | Number | 0 | ---- | 图标圆角 | | borderRadius | Number | 0 | ---- | 圆角 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | icon | String | ---- | ---- | 图标 可使用网络图片路径或者[图标库](https://www.iconfont.cn/collections/detail?cid=33) | | title | String | ---- | ---- | 标题 | | description | String | ---- | ---- | 简介 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "components": [ { "name": "link", "style": { "iconColor": "#f5f5f5",//图标颜色 "iconBorderRadius": 0,//图标圆角 "borderRadius": 0,//圆角 }, "staticData":{ "icon": "notification",//图标 "title": "这是一个链接",//标题 "description": "这是一个链接简介",//简介 "url": "https://www.baidu.com"//跳转网址 }//静态数据 }, { "name": "link", "style": { "iconColor": "#f5f5f5",//图标颜色 "iconBorderRadius": 0,//图标圆角 "borderRadius": 0,//圆角 }, "request": { "url": "https://www.test.com",//请求链接 "device": "电脑"//请求平台 },//请求 "dynamicData": { "icon": "@sel:tag.img[0]>>attr.src",//图片规则 "title": "@sel:tag.p[0]>>text",//标题规则 "description": "@sel:class.intro[0]>>text",//简介规则 "url": "detail?id=@sel:class.link[0]>>attr.href"//跳转路径(网址 | 页面) }//动态数据 } ] } ``` * links(链接栏) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | column | Number | 2 | ---- | 列数 | | borderRadius | Number | 0 | ---- | 圆角 | * 数据 | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | icon | String | ---- | ---- | 图标 可使用网络图片路径或者[图标库](https://www.iconfont.cn/collections/detail?cid=33) | | iconColor | String | ---- | ---- | 图标颜色 | | title | String | ---- | ---- | 标题 | | url | String | ---- | ---- | 跳转路径(支持在线网址和规则页面) | * 示例用法 ```json { "components": [ { "name": "links", "style": { "column": 2,//列数 "borderRadius": 0//圆角 }, "staticData": [{ "icon": "notifacation",//图标 可使用网络图片路径 "iconColor": "#f5f5f5",//图标颜色 "title": "链接",//标题 "url": "list"//跳转路径(网址 | 页面) },{ "icon": "notifacation",//图标 可使用网络图片路径 "iconColor": "#f5f5f5",//图标颜色 "title": "链接",//标题 "url": "list"//跳转路径(网址 | 页面) }]//静态数据 } { "name": "links", "style": { "column": 2,//列数 "borderRadius": 0//圆角 }, "request": { "url": "https://www.test.com",//请求链接 "device": "电脑"//请求平台 },//请求 "dynamicData": { "list": "@sel:tag.li",//列表规则 "icon": "@sel:tag.img[0]>>attr.src",//图片规则 "title": "@sel:tag.p[0]>>text",//标题规则 "url": "detail?id=@sel:class.link[0]>>attr.href"//跳转路径(网址 | 页面) }//动态数据 } ] } ``` * card(卡片) * style(样式) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | cardTitle | String | ---- | ---- | 卡片标题 | | cardIcon | String | ---- | ---- | 卡片图标 可使用网络图片路径或者[图标库](https://www.iconfont.cn/collections/detail?cid=33) | | cardIconColor | String | ---- | ---- | 卡片图标颜色 | | cardDescription | String | ---- | ---- | 卡片简介 | | enableRefresh | Number | 0 | 1/0 | 开启换一组功能(需要配合cellCount使用,cellCount用来控制每一组的最大数量) | | enableScroll | Number | 0 | 1/0 | 开启滚动功能 | | enableTopCard | Number | 0 | 1/0 | 开启顶部卡片显示 | | topCellName | String | ---- | h-cell/v-cell/img-cell/text-cell/tag-cell/c-cell/t-cell | 顶部卡片(默认和cellName相同) | | topCellImageWidth | Number | 120 | ---- | 顶部卡片图片宽度 | | topCellImageHeight | Number | 160 | ---- | 顶部卡片图片高度 | | topCellImageBorderRadius | Number | 10 | ---- | 顶部卡片图片圆角 | | topCellImageTipSize | Number | 20 | ---- | 顶部卡片图片提示尺寸 | | topCellTitleLines | Number | 1 | ---- | 顶部卡片标题多行省略 | | topCellDescriptionLines | Number | 3 | ---- | 顶部卡片简介多行省略 | | moreText | String | ---- | ---- | 更多按钮文字 | | moreUrl | String | ---- | ---- | 更多按钮链接(支持在线网址和规则页面) | | cellName | String | ---- | h-cell/v-cell/img-cell/text-cell/tag-cell/c-cell/t-cell | 单元格 | | cellImageWidth | Number | 120 | ---- | 单元格图片宽度 | | cellImageHeight | Number | 160 | ---- | 单元格图片高度 | | cellImageBorderRadius | Number | 10 | ---- | 单元格图片圆角 | | cellImageTipSize | Number | 20 | ---- | 单元格图片提示尺寸 | | cellTitleLines | Number | 1 | ---- | 单元格标题多行省略 | | cellDescriptionLines | Number | 3 | ---- | 单元格简介多行省略 | | cellColumn | Number/String | 3 | ---- | 列数 | | cellCount | Number/String | auto | ---- | 列表总数 | | cellGap | Number | 30 | ---- | 间距 | | cellWidth | Number | 300/auto | ---- | 单项单元格的宽度(仅在enableScroll为1和cellColumn为auto时生效) | | borderRadius | Number | 0 | ---- | 圆角 | | subsectionColumn | Number/String | auto | auto/任意整数 | 分段器列数 | | subsectionSelectedColor | String | ---- | ---- | 分段器选中颜色 | * data(数据) | 属性名 | 类型 | 默认值 | 可选值 | 说明 | | :----- | :----: | :----: | :----: | :---- | | subsection | Array | ---- | ---- | 分段数据 | * 示例用法(该组件需要配合cell单元格使用) ```json { "components": [ //横向单元格 { "name": "card", "style": { "cardTitle": "作者", "cellName": "h-cell", "cellColumn": 1, "cellImageWidth": 80, "cellImageHeight": 80, "cellDescriptionLines": 1, "cellImageBorderRadius": 80 }, "request": { "url": "/book/{{id}}.html", "device": "电脑" }, "dynamicData": { "list": "@sel:class.novelist", "title": "@sel:class.name[0]>>tag.a[0]>>text", "cover": "@sel:tag.img[0]>>attr.src", "description": "@sel:class.about[0]>>text", "url": "user?id=@sel:class.name[0]>>tag.a[0]>>attr.href@replace:/user/info?id=" } }, //竖向单元格 { "name": "card", "style": { "cardTitle": "推荐阅读", "cellName": "v-cell" }, "request": { "url": "/book/{{id}}.html", "device": "电脑" }, "dynamicData": { "list": "@sel:class.side-show-image-list[0]>>class.side-show-image-item", "title": "@sel:tag.img[0]>>attr.alt", "cover": "@sel:tag.img[0]>>attr.src", "url": "book?id=@sel:tag.a[0]>>attr.href@match:book&es;/>>.html>>1" } }, //图片单元格 { "name": "card", "style": { "cardTitle": "版权强推", "cellName": "img-cell", "cellColumn": 2, "cellImageHeight": 140, "enableTopCard": 1 }, "request": { "device": "电脑" }, "dynamicData": { "list": "@sel:class.blog-list[0]>>tag.li", "cover": "@sel:class.lazy[0]>>attr.data-original", "url": "@sel:tag.a[0]>>attr.href" } }, //文本单元格 { "name": "card", "style": { "cellName": "text-cell" }, "request": { "url": "/article/{{$1}}/{{page}}", "device": "电脑" }, "dynamicData": { "list": "@sel:class.article[0]>>tag.li", "title": "@sel:class.title[0]>>text", "subtitle": "@sel:class.top_20[0]>>text", "url": "@sel:class.right[0]>>tag.img[0]article?id=@sel:class.title[0]>>attr.href@split:article/>>1&background=@sel:class.right[0]>>tag.img[0]>>attr.srcarticle?id=@sel:class.title[0]>>attr.href@split:article/>>1&background=@sel:class.face[0]>>attr.src" } }, //标签单元格 { "name": "card", "style": { "cardTitle": "热门搜索", "cellName": "tag-cell", "cellColumn": "auto" }, "request": { "url": "/book/fenlei.html", "device": "电脑" }, "dynamicData": { "list": "@sel:id.album_tabs>>tag.li[2]>>tag.a", "title": "@sel:text", "url": "detail?id=@sel:attr.href@match:cate->>.html>>1&navigationTitle=@sel:text" } }, //评论单元格 { "name": "card", "style": { "cardTitle": "热门评论", "cellName": "c-cell", "cellColumn": 1 }, "request": { "url": "/video_{{id}}", "device": "手机" }, "dynamicData": { "list": "@sel:class.main-comm-list[0]>>class.comm-li", "title": "@sel:class.comm-name[0]>>text", "subtitle": "@sel:class.date[0]>>text", "avatar": "@sel:class.comm-hdimg[0]>>attr.style@match:url&es;(>>&es;);>>1", "content": "@sel:class.comm-cont[0]>>text", "subComments": { "list": "@sel:class.reply-li", "title": "@sel:class.comm-reply-title[0]>>text", "subtitle": "@sel:class.date[0]>>text", "content": "@sel:class.comm-reply-cont[0]>>text" }, "score": "@sel:attr.data-score", "commentId": "@sel:attr.id" } }, //讨论\帖子 单元格 { "name": "card", "style": { "cardTitle": "分类", "cellName": "t-cell", "cellColumn": 1 }, "request": { "device": "手机" }, "dynamicData": { "list": "@json:data.list", "title": "@json:author", "subtitle": "@json:ghType@equal:haokan官方账号@json:authorWishes", "subtext": "@json:ghType@equal:haokan@json:playcntText | @json:durationText", "avatar": "@json:authorIcon", "description": "#@json:videoInfo.title", "video": { "title": "@json:videoInfo.title", "cover": "@json:videoInfo.poster", "src": "@json:videoInfo.clarityUrl[0].url" }, "url": "video?id=@json:vid" } }, //开启分类 { "name": "card", "style": { "cardTitle": "分类", "cellName": "tag-cell", "cellColumn": "auto" }, "request": { "url": "/book/fenlei.html", "device": "电脑" }, "staticData": { "subsection": ["热血", "推理", "悬疑"] }, "dynamicData": { "list": [{ "list": "@sel:id.album_tabs>>tag.li[2]>>tag.a", "title": "@sel:text", "url": "detail?id=@sel:attr.href@match:cate->>.html>>1&navigationTitle=@sel:text" },{ "list": "@sel:id.album_tabs>>tag.li[3]>>tag.a", "title": "@sel:text", "url": "detail?id=@sel:attr.href@match:cate->>.html>>1&navigationTitle=@sel:text" },{ "list": "@sel:id.album_tabs>>tag.li[4]>>tag.a", "title": "@sel:text", "url": "detail?id=@sel:attr.href@match:cate->>.html>>1&navigationTitle=@sel:text" }] } }, //开启刷新功能 { "name": "card", "style": { "cardTitle": "最近应援", "cardDescription": "大佬万岁\/(^o^)/ ", "cellName": "v-cell", "cellColumn": 4, "cellCount": 4,//每组数量为4 "enableRefresh": 1,//开启换一组功能 "cellImageHeight": 160 }, "request": { "url": "/book.html", "device": "电脑" }, "dynamicData": { "list": "@sel:class.reward-list[0]>>tag.a", "title": "@sel:class.book-name[0]>>text", "subtitle": "@sel:class.reward-detail[0]>>text", "cover": "@sel:class.lazy[0]>>attr.data-original", "url": "book?id=@sel:attr.href@match:book&es;/>>.html>>1" } } ] } ``` * 组件支持动态生成,示例如下: ```json { "components": [ { //不填写name属性,填写request和components属性,表示根据请求内容动态生成组件,对于相同的组件可以一次生成,避免一个一个编辑 "request": { "url": "/api/stations?classifyId=4" }, //components为数组,可以添加多个组件,表示动态生成多个组件,所有属性都和规则属性一样,可以填写规则获取内容 "components": [{ "list": "@json:data",//list属性和规则的list属性是一样的,list获得多少条内容,就生成多少个本组件 "name": "card", "style": { "cardTitle": "@json:name", "cellName": "v-cell", "cellColumn": 2, "cellImageHeight": 200, "moreUrl": "more?id=@json:id&navigationTitle=@json:name", "moreText": "更多" }, "data": { "list": "@json:list", "title": "@json:title", "subtitle": "@json:tagTitles@join:·", "cover": "@json:coverImg", "url": "detail?id=@json:id" } }] } ] } ```