123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- import DOMPurify from 'dompurify';
- import {
- changeNumToHan
- } from '@/utils/transform';
- // 选项类型
- export const optionTypeList = [{
- value: 'letter',
- label: '字母'
- },
- {
- value: 'number',
- label: '数字'
- },
- {
- value: 'capital',
- label: '大写字母'
- },
- {
- value: 'bracket_number',
- label: '括号数字'
- },
- ];
- // 题号选项
- export const computeOptionMethods = {
- [optionTypeList[0].value]: (i) => `${String.fromCharCode(97 + i)}.`,
- [optionTypeList[1].value]: (i) => `${i + 1}.`,
- [optionTypeList[2].value]: (i) => `${String.fromCharCode(65 + i)}.`,
- // [optionTypeList[2].value]: (i) => changeNumToHan(i + 1) + '.',
- // [optionTypeList[3].value]: (i) => `(${i + 1})`, //中文括号
- [optionTypeList[3].value]: (i) => `(${i + 1})`, //英文括号
- };
- /**
- * 改变选项类型
- * @param {object} data 数据
- */
- export function changeOptionType(data) {
- let index = optionTypeList.findIndex(({
- value
- }) => value === data.option_number_show_mode);
- data.option_number_show_mode = optionTypeList[index + 1]?.value || optionTypeList[0].value;
- }
- /**
- * 计算选项题号
- * @param {Number} i 序号
- * @param {String} option_number_show_mode 选项类型
- * @returns String 题号
- */
- export function computedQuestionNumber(i, option_number_show_mode) {
- const computationMethod = computeOptionMethods[option_number_show_mode];
- if (computationMethod) {
- return computationMethod(i);
- }
- return '';
- }
- // 题干类型
- export const stemTypeList = [{
- value: 'text',
- label: '纯文本'
- },
- {
- value: 'rich',
- label: '富文本'
- },
- ];
- // 分值类型
- export const scoreTypeList = [{
- value: 'aggregate',
- label: '总分'
- },
- {
- value: 'subdivision',
- label: '细分'
- },
- ];
- // 选择类型
- export const selectTypeList = [{
- value: 'single',
- label: '单选'
- },
- {
- value: 'multiple',
- label: '多选'
- },
- ];
- // 开关选项
- export const switchOption = [{
- value: 'true',
- label: '开启'
- },
- {
- value: 'false',
- label: '关闭'
- },
- ];
- // 题号类型
- export const questionNumberTypeList = [{
- value: 'recalculate',
- label: '重新计算'
- },
- {
- value: 'follow',
- label: '跟随上题'
- },
- ];
- // 选项类型列表
- export const option_type_list = [{
- value: 'right',
- label: '是'
- },
- {
- value: 'error',
- label: '非'
- },
- {
- value: 'incertitude',
- label: '不确定'
- },
- ];
- // 布局方式,horizontal 【横排】,vertical【竖排】
- export const layout_type_list = [{
- value: 'horizontal',
- label: '横排'
- },
- {
- value: 'vertical',
- label: '竖排'
- }
- ];
- // 答题模式列表
- export const answer_mode_list = [{
- value: 1,
- label: '练习模式'
- },
- {
- value: 2,
- label: '考试模式'
- }
- ];
- // 答题模式列表
- export const answer_status_list = [{
- value: 0,
- label: '未作答'
- },
- {
- value: 1,
- label: '客观题(正确)'
- },
- {
- value: 2,
- label: '客观题(错误)'
- },
- {
- value: 3,
- label: '主观题(已答)'
- }
- ];
- // 任务时间类型列表
- export const time_type_list = [{
- value: 0,
- label: '课前任务'
- },
- {
- value: 1,
- label: '课中任务'
- },
- {
- value: 2,
- label: '课后任务'
- },
- {
- value: 3,
- label: '练习任务'
- }
- ];
- // 任务完成状态列表
- export const task_finish_status_list = [{
- value: 0,
- label: '未开始'
- },
- {
- value: 1,
- label: '进行中'
- },
- {
- value: 2,
- label: '结束'
- }
- ];
- export const questionData = {
- share_record_id: '',
- parentType: '',
- answer_record_id: '',
- question_id: '',
- type: '', // 题型
- stem: '', // 题干
- option_number_show_mode: optionTypeList[0].value, // 选项类型
- description: '', // 描述
- option_list: [{
- content: '',
- mark: '',
- answer: '',
- checked: false
- }], // 选项
- question_list: [{ //阅读题特有
- id: '', // 小题id
- type: '', // 小题类型
- additional_type: '', // 附加类型多选单选等
- }],
- file_id_list: [], // 文件 id 列表
- file_list: [],
- audioSrc: '',
- answer: {
- answer_list: [],
- score: 0,
- score_type: scoreTypeList[0].value,
- }, // 答案
- // 题型属性
- property: {
- stem_type: stemTypeList[0].value, // 题干类型
- question_number: 1, // 题号
- is_enable_description: false, // 描述
- select_type: selectTypeList[0].value, // 选择类型
- is_enable_listening: true, // 是否听力
- score: 1, // 分值
- score_type: scoreTypeList[0].value, // 分值类型
- },
- // 其他属性
- other: {
- question_number_type: questionNumberTypeList[0].value, // 题号类型
- },
- user_answer: {},
- audio: new Audio(),
- playing: false,
- isSubSub: false, //子组件的子组件
- isLoaded: false, //数据加载完成
- remark: {}, //教师批注
- answer_mode: 1, //答题模式
- /**
- * 阅读题专用,用于切换题目时给阅读题小题答题控制赋值
- */
- isReadQuestionWatch: false,
- }
- export const answer_control = {};
- //是否直接切换题目索引
- export const isSwitchQuestionIndex = {};
- /**
- * 过滤 html,防止 xss 攻击
- * @param {String} html 需要过滤的html
- * @returns {String} 过滤后的html
- */
- export function sanitizeHTML(html) {
- html = html.replace(/<video[^>]*>/g, function(match) {
- if (match.includes('controlsList="')) {
- return match.replace(/controlsList="[^"]*"/,
- 'controlsList="nodownload nodirection noplaybackrate" disablePictureInPicture');
- } else {
- return match.replace('>', ' controlsList="nodownload nodirection noplaybackrate" disablePictureInPicture>');
- }
- });
- var platform = "android";
- uni.getSystemInfo({
- success: function(res) {
- platform = res.platform; // 操作系统类型,如 "android", "ios" 等
- }
- });
- if (platform === "android") {
- html = html.replace(/<audio[^>]*>/g, function(match) {
- if (match.includes('controlsList="')) {
- return match.replace(/controlsList="[^"]*"/,
- 'controlsList="nodownload nodirection noplaybackrate" style="height:47px"');
- } else {
- return match.replace('>',
- ' controlsList="nodownload nodirection noplaybackrate" style="height:47px">');
- }
- });
- html = html.replace(/<p><audio[^>]*>/g, function(match) {
- return match.replace('<p>', '<p style="width:47px;height:47px;overflow:hidden;border-radius:24px">');
- });
- } else {
- html = html.replace(/<audio[^>]*>/g, function(match) {
- if (match.includes('controlsList="')) {
- return match.replace(/controlsList="[^"]*"/,
- 'controlsList="nodownload nodirection noplaybackrate" style="height:27px;margin:0"');
- } else {
- return match.replace('>',
- ' controlsList="nodownload nodirection noplaybackrate" style="height:27px;margin:0">');
- }
- });
- html = html.replace(/<p><audio[^>]*>/g, function(match) {
- return match.replace('<p>',
- '<p style="width:40px;height:32px;background-color:#818181;overflow:hidden;border-radius:8px">'
- );
- });
- }
- return DOMPurify.sanitize(html);
- }
- /**
- * 是否开启
- * @param {String} value 值
- * @returns Boolean
- */
- export function isEnable(value) {
- return value === switchOption[0].value;
- }
- export const tone_data = [
- ['ā', 'á', 'ǎ', 'à', 'a'],
- ['ō', 'ó', 'ǒ', 'ò', 'o'],
- ['ē', 'é', 'ě', 'è', 'e'],
- ['ī', 'í', 'ǐ', 'ì', 'i'],
- ['ū', 'ú', 'ǔ', 'ù', 'u'],
- ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
- ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
- ['Ā', 'Á', 'Â', 'À', 'A'],
- ['Ō', 'Ó', 'Ô', 'Ò', 'O'],
- ['Ē', 'É', 'Ê', 'È', 'E'],
- ['Ī', 'Í', 'Î', 'Ì', 'I'],
- ['Ū', 'Ú', 'Û', 'Ù', 'U'],
- ];
- /**
- * 添加声调
- * @param {Number} number
- * @param {String} con
- * @returns String
- */
- export function addTone(number, con) {
- const zmList = ['a', 'o', 'e', 'i', 'u', 'v', 'ü', 'A', 'O', 'E', 'I', 'U'];
- let cons = con;
- if (number) {
- for (let i = 0; i < zmList.length; i++) {
- let zm = zmList[i];
- if (con.includes(zm)) {
- let zm2 = tone_data[i][number - 1];
- if (con.includes('iu')) {
- zm2 = tone_data[4][number - 1];
- cons = con.replace('u', zm2);
- } else if (con.includes('ui')) {
- zm2 = tone_data[3][number - 1];
- cons = con.replace('i', zm2);
- } else if (/yv|jv|qv|xv/.test(con)) {
- zm2 = tone_data[4][number - 1];
- cons = con.replace('v', zm2);
- } else if (/yü|jü|qü|xü/.test(con)) {
- zm2 = tone_data[4][number - 1];
- cons = con.replace('ü', zm2);
- } else {
- cons = con.replace(zm, zm2);
- }
- break;
- }
- }
- }
- return cons;
- }
- export function handleToneValue(valItem) {
- let numList = [];
- if (/[A-Za-zü]+\d/g.test(valItem)) {
- valItem.split('').forEach((item, i) => {
- if (/\d/.test(item)) {
- let numIndex = numList.length === 0 ? 0 : numList[numList.length - 1].index;
- let con = valItem.substring(numIndex, i).replace(/\d/g, '');
- numList.push({
- number: item,
- con,
- });
- }
- });
- } else {
- numList = [];
- }
- return numList.length === 0 ? [{
- con: valItem
- }] : numList;
- }
- export const svgNS = 'http://www.w3.org/2000/svg'; // SVG命名空间
|