zoukankan      html  css  js  c++  java
  • 【cml】wosi-demo

    推荐一个cml项目,https://github.com/Bowen7/wosi-demo
    呃呃,运行了项目只能够说开发者好牛逼,数据处理很厉害,

    这个是最后的结果,然后要进行效果查看,估计你得等明天
    哇塞,项目里面的数据处理我觉得其实有些麻烦,来来来,我们一起分析代码
    我们先来看数据处理部分



    这个是state状态部分

    const state = {
    	userInfo: {
    		days: 0,
    		plan: 25,
    		status: "normal",
    		date: ""
    	},
    	bookInfo: {
    		bookid: "",
    		bookName: "未选择单词书",
    		bookLength: 1,
    		curid: 0,
    		pass: 0
    	},
    	todayInfo: {
    		count: 0,
    		wordsLength: 0
    	},
    	books: [],
    	review: [],
    	words: [],
    	section: []
    };
    
    export default state;
    

    我们通过提交 mutation 的方式,而非直接改变 store.state
    现在我们来看看mutation中的内容

    //mutation-types.js
    export const UPDATE_USERINFO = "UPDATE_USERINFO";
    export const UPDATE_BOOKINFO = "UPDATE_BOOKINFO";
    export const UPDATE_TODAYINFO = "UPDATE_TODAYINFO";
    export const UPDATE_BOOKS = "UPDATE_BOOKS";
    export const UPDATE_REVIEW = "UPDATE_REVIEW";
    export const UPDATE_WORDS = "UPDATE_WORDS";
    export const UPDATE_SECTION = "UPDATE_SECITON";
    
    //srcstoremutations.js
    import {
    	UPDATE_USERINFO,
    	UPDATE_BOOKINFO,
    	UPDATE_TODAYINFO,
    	UPDATE_BOOKS,
    	UPDATE_REVIEW,
    	UPDATE_WORDS,
    	UPDATE_SECTION
    } from "./mutation-types";
    export default {
    	[UPDATE_USERINFO](state, info) {
    		state.userInfo = { ...state.userInfo, ...info };
    	},
    	[UPDATE_BOOKINFO](state, info) {
    		state.bookInfo = { ...state.bookInfo, ...info };
    	},
    	[UPDATE_TODAYINFO](state, info) {
    		state.todayInfo = { ...state.todayInfo, ...info };
    	},
    	[UPDATE_BOOKS](state, books) {
    		state.books = books.slice();
    	},
    	[UPDATE_REVIEW](state, review) {
    		state.review = review.slice();
    	},
    	[UPDATE_WORDS](state, words) {
    		state.words = words.slice();
    	},
    	[UPDATE_SECTION](state, section) {
    		state.section = section.slice();
    	}
    };
    

    Action 类似于 mutation,不同在于:
    Action 提交的是 mutation,而不是直接变更状态。
    Action 可以包含任意异步操作。
    我们来看看Action中的内容

    //srcstoreaction-types.js
    export const GET_INFO = "GET_INFO";
    export const GET_USER_INFO = "GET_USER_INFO";
    export const GET_BOOK_INFO = "GET_BOOK_INFO";
    export const GET_TODAY_INFO = "GET_TODAY_INFO";
    export const GET_BOOKS = "GET_BOOKS";
    export const CHOOSE_BOOK = "CHOOSE_BOOK";
    export const CHANGE_PLAN = "CHANGE_PLAN";
    export const GET_REVIEW = "GET_REVIEW";
    export const GET_WORDS = "GET_WORDS";
    export const GET_SECTION = "GET_SECTION";
    export const SET_WORDS_LENGTH = "SET_WORDS_LENGTH";
    export const ADD_TODAY_COUNT = "ADD_TODAY_COUNT";
    export const ADD_USER_PASS = "ADD_USER_PASS";
    export const PUSH_WORDS_TO_SECTION = "PUSH_WORDS_TO_SECTION";
    export const PUSH_WORDS_TO_REVIEW = "PUSH_WORDS_TO_REVIEW";
    export const POST_RECORD = "POST_RECORD";
    
    //srcstoreactions.js
    //这个里面的好难,我不想动脑筋看
    import cml from "chameleon-api";
    import dayjs from "dayjs";
    import * as mutationTypes from "./mutation-types";
    import * as actionTypes from "./action-types";
    const SECTION_LENGTH = 7;
    export default {
    	[actionTypes.GET_INFO]({ dispatch }) {
    		return Promise.all([
    			dispatch(actionTypes.GET_USER_INFO),
    			dispatch(actionTypes.GET_BOOK_INFO),
    			dispatch(actionTypes.GET_TODAY_INFO)
    		]);
    	},
    	/**
    	 * 获取user信息
    	 * 先从storage中拿,拿不到,再去请求(后面类似方法基本都是这么做的)
    	 * date用来记录user信息的时效,第二天需重新请求
    	 */
    	async [actionTypes.GET_USER_INFO]({ commit, state }) {
    		const date = dayjs().format("YY-MM-DD");
    		let userInfo;
    		try {
    			userInfo = await cml.getStorage("userInfo");
    		} catch (error) {}
    
    		(!userInfo || date !== userInfo.date) &&
    			((userInfo = await cml.get({
    				url: "/api/user/info"
    			})),
    			await cml.setStorage("userInfo", { ...userInfo, date }));
    		!!userInfo && commit(mutationTypes.UPDATE_USERINFO, userInfo);
    	},
    	/**
    	 * 获取词库信息
    	 */
    	async [actionTypes.GET_BOOK_INFO]({ commit }) {
    		let bookInfo;
    		try {
    			bookInfo = await cml.getStorage("bookInfo");
    		} catch (error) {}
    		!bookInfo &&
    			((bookInfo = await cml.get({
    				url: "/api/book/info"
    			})),
    			await cml.setStorage("bookInfo", bookInfo));
    		!!bookInfo && commit(mutationTypes.UPDATE_BOOKINFO, bookInfo);
    	},
    	/**
    	 * 获取今日学习情况
    	 * todo success后 清空缓存的情况
    	 */
    	async [actionTypes.GET_TODAY_INFO]({ commit, state }) {
    		let todayInfo;
    		try {
    			todayInfo = await cml.getStorage("todayInfo");
    		} catch (error) {}
    		!!todayInfo
    			? commit(mutationTypes.UPDATE_TODAYINFO, todayInfo)
    			: cml.setStorage("todayInfo", state.todayInfo);
    	},
    	/**
    	 * 获取单词库
    	 * 不存stroage,保持时效
    	 */
    	async [actionTypes.GET_BOOKS]({ commit }) {
    		const books = await cml.get({
    			url: "/api/book"
    		});
    		!!books && commit(mutationTypes.UPDATE_BOOKS, books);
    	},
    	/**
    	 * 选择词库
    	 * url:"/api/user/info/2" 是为了mock出不同status的情况
    	 * 对接前需修改
    	 */
    	async [actionTypes.CHOOSE_BOOK]({ commit, state }, payload) {
    		const data = await cml.request({
    			url: "/api/book",
    			data: payload,
    			method: "PUT"
    		});
    		commit(mutationTypes.UPDATE_BOOKINFO, data);
    		await cml.setStorage("bookInfo", data);
    		if (state.userInfo.status === "new") {
    			let userInfo = await cml.getStorage("userInfo");
    			const data = await cml.get({
    				url: "/api/user/info/2"
    			});
    			userInfo = { ...userInfo, ...data };
    			await cml.setStorage("userInfo", userInfo),
    				commit(mutationTypes.UPDATE_USERINFO, userInfo);
    		}
    	},
    	/**
    	 * 更改每日学习计划
    	 */
    	async [actionTypes.CHANGE_PLAN]({ commit }, payload) {
    		let { plan } = payload;
    		plan = parseInt(plan);
    		await cml.request({
    			url: "/api/plan",
    			data: { plan },
    			method: "PUT"
    		});
    		commit(mutationTypes.UPDATE_USERINFO, { plan: plan });
    		const userInfo = await cml.getStorage("userInfo");
    		userInfo.plan = plan;
    		await cml.setStorage("userInfo", userInfo);
    	},
    	/**
    	 * 获取复习单词
    	 */
    	async [actionTypes.GET_REVIEW]({ commit }) {
    		let review = [];
    		try {
    			review = await cml.getStorage("review");
    		} catch (error) {}
    		review.length === 0 &&
    			(review = await cml.get({
    				url: "/api/review"
    			}));
    		commit(mutationTypes.UPDATE_REVIEW, review);
    	},
    	/**
    	 * 获取新单词,与复习单词合并为今日要背的单词words
    	 * 重置review,留以存放第二天需要复习的单词
    	 * 过滤熟练度5和6的单词
    	 * 初始化status和times
    	 */
    	async [actionTypes.GET_WORDS]({ commit, state, dispatch }) {
    		let words;
    		try {
    			words = await cml.getStorage("words");
    		} catch (error) {}
    		if (!words) {
    			await dispatch(actionTypes.GET_REVIEW);
    			const data = await cml.get({
    				url: "/api/words"
    			});
    			const newWords = data.map(item => {
    				return {
    					...item,
    					proficiency: 0
    				};
    			});
    			const review = state.review.filter(item => {
    				const { proficiency } = item;
    				return proficiency === 5 || proficiency === 6;
    			});
    			const _review = state.review.filter(item => {
    				const { proficiency } = item;
    				return !(proficiency === 5 || proficiency === 6);
    			});
    			words = [..._review, ...newWords];
    			words = words.map(item => {
    				return {
    					...item,
    					status: 0,
    					times: 0
    				};
    			});
    			words.sort(() => {
    				return Math.random() - 0.5;
    			});
    			await cml.setStorage("words", words);
    			await cml.setStorage("review", review);
    			commit(mutationTypes.UPDATE_REVIEW, review);
    
    			await dispatch(actionTypes.SET_WORDS_LENGTH, words.length);
    		}
    		commit(mutationTypes.UPDATE_WORDS, words);
    	},
    	/**
    	 * 获取section,
    	 * section用来存放固定数量的单词
    	 * 每次随机从section中取一个单词出来
    	 */
    	async [actionTypes.GET_SECTION]({ commit, state }) {
    		let section;
    		try {
    			section = await cml.getStorage("section");
    		} catch (error) {}
    		if (!section) {
    			section = state.words.splice(0, SECTION_LENGTH);
    			await cml.setStorage("section", section);
    		}
    		commit(mutationTypes.UPDATE_SECTION, section);
    	},
    	/**
    	 * 设置wordsLength,即当天的单词量
    	 */
    	async [actionTypes.SET_WORDS_LENGTH]({ commit }, wordsLength) {
    		const todayInfo = await cml.getStorage("todayInfo");
    		commit(mutationTypes.UPDATE_TODAYINFO, { wordsLength });
    		await cml.setStorage("todayInfo", { ...todayInfo, wordsLength });
    	},
    	/**
    	 * count自增1,count是当天已学习的单词
    	 */
    	async [actionTypes.ADD_TODAY_COUNT]({ commit, state }) {
    		const todayInfo = await cml.getStorage("todayInfo");
    		let count = state.todayInfo.count;
    		commit(mutationTypes.UPDATE_TODAYINFO, { count: ++count });
    		await cml.setStorage("todayInfo", { ...todayInfo, count });
    	},
    	/**
    	 * pass自增1,pass是熟词的数量
    	 */
    	async [actionTypes.ADD_USER_PASS]({ commit, state }) {
    		const bookInfo = await cml.getStorage("bookInfo");
    		let pass = state.bookInfo.pass;
    		commit(mutationTypes.UPDATE_BOOKINFO, { pass: ++pass });
    
    		await cml.setStorage("bookInfo", { ...bookInfo, pass });
    	},
    	/**
    	 * 将当前的单词取出,附上属性,重新放到section末尾
    	 */
    	async [actionTypes.PUSH_WORDS_TO_SECTION](
    		{ commit, state },
    		{ index, proficiency, status, times }
    	) {
    		const section = state.section.slice();
    		const word = {
    			...section.splice(index, 1)[0],
    			proficiency,
    			status,
    			times
    		};
    		section.push(word);
    		commit(mutationTypes.UPDATE_SECTION, section);
    		await cml.setStorage("section", section);
    	},
    	/**
    	 * 将当前的单词取出,附上属性,放到review中,
    	 * 并从words中取出一单词放入section
    	 */
    	async [actionTypes.PUSH_WORDS_TO_REVIEW](
    		{ commit, dispatch, state },
    		{ index, proficiency }
    	) {
    		const section = state.section.slice();
    		const words = state.words.slice();
    		let word = { ...section.splice(index, 1)[0], proficiency };
    		if (proficiency !== 8) {
    			let review = await cml.getStorage("review");
    			review.push(word);
    			await cml.setStorage("review", review);
    		} else {
    			await dispatch(actionTypes.ADD_USER_PASS);
    		}
    
    		if (words.length > 0) {
    			word = { ...words.shift() };
    			section.unshift(word);
    			await cml.setStorage("words", words);
    			commit(mutationTypes.UPDATE_WORDS, words);
    		}
    		await cml.setStorage("section", section);
    		commit(mutationTypes.UPDATE_SECTION, section);
    		await dispatch(actionTypes.ADD_TODAY_COUNT);
    	},
    	/**
    	 * 打卡
    	 */
    	async [actionTypes.POST_RECORD]({ commit }, { review, pass }) {
    		await cml.removeStorage("words");
    		const data = await cml.post({
    			url: "/api/record",
    			data: {
    				review,
    				pass
    			}
    		});
    		const { status, days, curid, pass: _pass } = data;
    		commit(mutationTypes.UPDATE_USERINFO, { days, status });
    		commit(mutationTypes.UPDATE_BOOKINFO, { curid, pass: _pass });
    		let userInfo = await cml.getStorage("userInfo");
    		let bookInfo = await cml.getStorage("bookInfo");
    		userInfo = { ...userInfo, days, status };
    		await cml.setStorage("userInfo", userInfo);
    		bookInfo = { ...bookInfo, curid, pass: _pass };
    		await cml.setStorage("bookInfo", bookInfo);
    	}
    };
    
    //srcstoreindex.js
    import actions from './actions'
    import getters from './getters'
    import state from './state'
    import mutations from './mutations'
    import createStore from "chameleon-store";
    
    export default createStore({
      actions,
      getters,
      state,
      mutations
    })
    

    先看效果

    再看代码

    <template>
      <view class="wrapper">
    		<view class="item">
    			<view 
    				class="return"
    				c-bind:tap="pageReturn"
    			>
    				<image 
    					src="{{leftImgSrc}}" 
    					style=" 50cpx;height:50cpx;"
    				/>
    				<text>返回</text>
    			</view>
    		</view>
    		<view class="item">
    			<text>夜间模式(正在开发)</text>
    			<switch
    				checked="{{ switchValue }}"
    				c-bind:change="switchChange"
    			>
    			</switch>
    		</view>
    		<view class="item" c-bind:tap="selectBook">
    			<text>单词书</text>
    			<view class="item-right">
    				<text>{{ bookInfo.bookName }}</text>
    				<image 
    					src="{{rightImgSrc}}" 
    					style=" 30cpx;height:30cpx;"
    				/>
    			</view>
    		</view>
    		<view class="item" c-bind:tap="selectPlan">
    			<text>每日新词数</text>
    			<view class="item-right">
    				<text>{{ userInfo.plan }}</text>
    				<image 
    					src="{{ rightImgSrc }}" 
    					style=" 30cpx;height:30cpx;"
    				/>
    			</view>
    		</view>
    		<c-picker-panel 
    			show="{{bookPickerShow}}" 
    			height="{{500}}" 
    			header-height="{{100}}"
    			c-bind:cancel="bookCancel"
    			c-bind:confirm="bookConfirm"
    		>
    			<c-picker-item 
    				text-align="center" 
    				height="{{400}}" 
    				data="{{bookSelects}}" 
    				default-index="{{bookDefaultIndex}}"
    				c-bind:selectchange="planSelectchange"
    			>
    			</c-picker-item>
    		</c-picker-panel>
    
    		<c-picker-panel 
    			show="{{planPickerShow}}" 
    			height="{{500}}" 
    			header-height="{{100}}"
    			c-bind:cancel="planCancel"
    			c-bind:confirm="planConfirm"
    		>
    			<c-picker-item 
    				text-align="center" 
    				height="{{400}}" 
    				data="{{planSelects}}" 
    				default-index="{{planDefaultIndex}}"
    				c-bind:selectchange="planSelectchange"
    			>
    			</c-picker-item>
    		</c-picker-panel>
    		<c-loading loading="{{loading}}">
    		</c-loading>
      </view>
    
    
    </template>
    
    <script>
    import cml from "chameleon-api";
    import store from "../../store";
    import { CHOOSE_BOOK, CHANGE_PLAN, GET_BOOKS } from "../../store/action-types";
    class Index {
    	data = {
    		leftImgSrc: require("../../assets/images/left.png"),
    		rightImgSrc: require("../../assets/images/right.png"),
    		bookSelects: [""],
    		planSelects: [
    			"5",
    			"10",
    			"15",
    			"20",
    			"25",
    			"30",
    			"35",
    			"40",
    			"45",
    			"50"
    		],
    		bookPickerShow: false,
    		planPickerShow: false,
    		loading: false,
    		bookIndex: 0,
    		planIndex: 0,
    		switchValue: false
    	};
    
    	beforeCreate() {
    		cml.setTitle("我思背单词");
    	}
    
    	computed = store.mapState({
    		bookInfo: "bookInfo",
    		userInfo: "userInfo",
    		books: "books",
    		planDefaultIndex() {
    			return this.planSelects.indexOf(this.userInfo.plan + "");
    		},
    		bookDefaultIndex() {
    			let index = this.bookSelects.indexOf(this.bookInfo.bookName);
    			index === -1 && (index = 0);
    			return index;
    		}
    	});
    
    	methods = {
    		switchChange(e) {
    			this.switchValue = e.detail.value;
    		},
    		bookCancel() {
    			this.bookPickerShow = false;
    		},
    		async bookConfirm() {
    			this.loading = true;
    			const book = this.books[this.bookIndex];
    			const { id: bookid } = book;
    			store.dispatch(CHOOSE_BOOK, { bookid });
    			this.bookPickerShow = false;
    			this.loading = false;
    		},
    		planCancel() {
    			this.planPickerShow = false;
    		},
    		async planConfirm() {
    			this.loading = true;
    			const plan = this.planSelects[this.planIndex];
    			await store.dispatch(CHANGE_PLAN, { plan });
    			this.loading = false;
    			this.planPickerShow = false;
    		},
    		async selectBook() {
    			this.loading = true;
    			this.bookPickerShow = true;
    			await store.dispatch(GET_BOOKS);
    			this.bookSelects = this.books.map(item => {
    				return item.name;
    			});
    			this.loading = false;
    		},
    		selectPlan() {
    			this.planPickerShow = true;
    		},
    		bookSelectchange(e) {
    			this.bookIndex = e.detail.index;
    		},
    		planSelectchange(e) {
    			this.planIndex = e.detail.index;
    		},
    		pageReturn(){
    			cml.navigateBack();
    		}
    	};
    }
    
    export default new Index();
    
    </script>
    <style scoped>
      @import './index.css';
    </style>
    <script cml-type="json">
    {
      "base": {
        "usingComponents": {
          "c-picker-panel": "cml-ui/components/c-picker-panel/c-picker-panel",
          "c-picker-item": "cml-ui/components/c-picker-item/c-picker-item",
          "c-loading": "cml-ui/components/c-loading/c-loading"
        }
      }
    }
    </script>
    
    //srcpages
    eciteindex.cml
    <template>
      <view class="wrapper">
    		<view class="nav">
    			<view 
    				class="return"
    				c-bind:tap="pageReturn"
    			>
    				<image 
    					src="{{leftImgSrc}}" 
    					style=" 50cpx;height:50cpx;"
    				/>
    				<text>返回</text>
    			</view>
    		</view>
        <view class="top-view">
          <text class="word">{{word.word}}</text>
          <view class="ipa-view">
            <text class="ipa" 
            c-if="{{!!word.phonetic}}"
            >[{{word.phonetic}}]</text>
            <image 
              src="{{soundImgSrc}}" 
              c-bind:tap="pronounce"
              style=" 40cpx;height:40cpx;"
            />
          </view>
          <audio
          src="{{src}}"
          >
          </audio>
        </view>
        <view 
          class="{{translationShow?'center-view-show':'center-view'}}"
          c-bind:tap="showTranslation"
        > 
          <text c-if="{{translationShow}}">{{translation}}</text>
          <block c-else="{{true}}">
            <image 
              src="{{eyeImgSrc}}" 
              style=" 40cpx;height:40cpx;"
            />
            <text class="tip">轻触查看释义</text>
          </block>
        </view>
        <view class="bottom-view">
          <button
            text="太简单"
            btn-style="background:#5cb4bd;600cpx;"
            c-bind:onclick="handleEasy"
            c-if="{{showEasyButton}}"
    				class="recite-button"
          />  
          <view class="info_view" c-else>
            <text>这个单词背过</text>
          </view>
          <button
            text="认识"
            btn-style="background:#5cb4bd;600cpx;"
            c-bind:onclick="handleCognizant"
    				class="recite-button"
          />  
          <button
            text="不认识"
            btn-style="background:#5cb4bd;600cpx;"
            c-bind:onclick="handleIncognizant"
    				class="recite-button"
          />  
        </view>
        <view class="progress-view">
          <text class="progress">{{
            todayInfo.count
          }}/{{
            todayInfo.wordsLength
          }}</text>
          <progress percent="{{percent}}"/>
        </view>
        <c-dialog 
          show="{{end}}"
          title="今日单词已背完"
          mask="{{true}}"
          icon-type="success"
          content=""
          icon-style="{{iconStyle}}"
          confirm-text="打卡"
          c-bind:confirm="handleRecord"
        >
        </c-dialog>
        <c-loading loading="{{loading}}"></c-loading>
      </view>
    </template>
    
    <script>
    import cml from "chameleon-api";
    import store from "../../store";
    import {
    	PUSH_WORDS_TO_REVIEW,
    	PUSH_WORDS_TO_SECTION,
    	GET_SECTION,
    	POST_RECORD
    } from "../../store/action-types";
    const soundBaseUrl = "https://wosiwords.oss-cn-hangzhou.aliyuncs.com/mp3";
    class Index {
    	data = {
    		src: "",
    		leftImgSrc: require("../../assets/images/left.png"),
    		soundImgSrc: require("../../assets/images/sound.png"),
    		eyeImgSrc: require("../../assets/images/eye.png"),
    		translationShow: false,
    		showEasyButton: true,
    		loading: false,
    		word: {},
    		sectionIndex: 0,
    		end: false,
    		iconStyle: {
    			 "60cpx",
    			height: "60cpx"
    		},
    		viewportHeight: 0
    	};
    	computed = store.mapState({
    		todayInfo: "todayInfo",
    		words: "words",
    		section: "section",
    		translation() {
    			if (!!this.word.translation) {
    				return `${this.word.translation.slice(1)}`;
    			}
    			return "";
    		},
    		percent(state) {
    			return state.todayInfo.wordsLength === 0
    				? 0
    				: (state.todayInfo.count / state.todayInfo.wordsLength) * 100;
    		}
    	});
    	watch = {
    		word: function(newVal) {
    			const { proficiency, status, times } = newVal;
    			this.showEasyButton =
    				proficiency === 0 && status === 0 && times === 0 ? true : false;
    		}
    	};
    	beforeCreate() {
    		cml.setTitle("我思背单词");
    	}
    
    	async mounted() {
    		await store.dispatch(GET_SECTION);
    		this.getRandomWord();
    	}
    	methods = {
    		/**
    		 * 点击太简单按钮
    		 * 单词熟悉度规则index/index.cml中有描述
    		 */
    		async handleEasy() {
    			const englishWord = this.word.word;
    			const { sectionIndex } = this;
    			await store.dispatch(PUSH_WORDS_TO_REVIEW, {
    				index: sectionIndex,
    				proficiency: 8
    			});
    			this.getRandomWord();
    			cml.showToast({
    				message: `单词${englishWord}加入熟词`,
    				duration: 1000
    			});
    		},
    		/**
    		 * 点击认识按钮
    		 * 单词熟悉度规则index/index.cml中有描述
    		 */
    		async handleCognizant() {
    			const { sectionIndex } = this;
    			let { proficiency, status, times, word: englishWord } = this.word;
    			if (proficiency === 7) {
    				await store.dispatch(PUSH_WORDS_TO_REVIEW, {
    					index: sectionIndex,
    					proficiency: 8
    				});
    				cml.showToast({
    					message: `单词${englishWord}加入熟词`,
    					duration: 1000
    				});
    			} else if (status === 2 || (proficiency === 4 && status === 1)) {
    				if (proficiency === 4) {
    					if (times === 0) {
    						proficiency++;
    					}
    				} else {
    					if (times === 0) {
    						proficiency += 2;
    					} else {
    						proficiency++;
    					}
    				}
    				await store.dispatch(PUSH_WORDS_TO_REVIEW, {
    					index: sectionIndex,
    					proficiency
    				});
    			} else {
    				if (proficiency === 0 && status === 0 && times === 0) {
    					proficiency = 2;
    					status = 1;
    				} else {
    					status++;
    				}
    				await store.dispatch(PUSH_WORDS_TO_SECTION, {
    					index: sectionIndex,
    					proficiency,
    					status
    				});
    			}
    			this.getRandomWord();
    		},
    		/**
    		 * 点击不认识按钮
    		 * 单词熟悉度规则index/index.cml中有描述
    		 */
    		async handleIncognizant() {
    			const { sectionIndex } = this;
    			let { proficiency, status, times } = this.word;
    			if ((proficiency === 7 || proficiency === 4) && status === 0) {
    				proficiency === 7 ? (proficiency = 4) : (proficiency = 3);
    				time++;
    			} else {
    				times++;
    			}
    			await store.dispatch(PUSH_WORDS_TO_SECTION, {
    				index: sectionIndex,
    				proficiency,
    				status,
    				times
    			});
    			this.getRandomWord();
    		},
    		/**
    		 * 从section中随机拿单词
    		 */
    		getRandomWord() {
    			this.translationShow = false;
    			if (this.section.length === 0) {
    				this.end = true;
    				return;
    			}
    			const length = this.section.length;
    			let index;
    			if (length > 2) {
    				index = Math.floor(Math.random() * (length - 3));
    			} else {
    				index = 0;
    			}
    			this.sectionIndex = index;
    			this.word = this.section[index];
    			this.pronounce();
    		},
    		pronounce() {
    			const { word } = this;
    			this.src =
    				`${soundBaseUrl}/${word.word}.mp3#` + new Date().getTime();
    		},
    		showTranslation() {
    			this.translationShow = true;
    		},
    		/**
    		 * 打卡
    		 */
    		async handleRecord() {
    			this.end = false;
    			this.loading = true;
    			const review = await cml.getStorage("review");
    			const bookInfo = await cml.getStorage("bookInfo");
    			await store.dispatch(POST_RECORD, { review, pass: bookInfo.pass });
    			this.loading = false;
    			cml.navigateTo({
    				path: "/pages/index/index"
    			});
    		},
    		pageReturn(){
    			cml.navigateBack();
    		}
    	};
    }
    
    export default new Index();
    
    </script>
    <style scoped>
      @import './index.css';
    </style>
    <script cml-type="json">
    {
      "base": {
        "usingComponents": {
          "progress": "/components/progress/progress",
          "record-circle": "/components/record-circle/record-circle",
          "audio": "/components/audio/audio",
          "c-loading": "cml-ui/components/c-loading/c-loading",
          "c-dialog": "cml-ui/components/c-dialog/c-dialog"
        }
      }
    }
    </script>
    
    <template>
      <view class="wrapper">
        <image 
          src="{{settingImgSrc}}" 
          style="60cpx;height:60cpx;"
          class="setting"
          c-bind:tap="gotoSetting"
        />
        <view class="top-view">
          <text class="title">{{title}}</text>
          <text class="task">今日单词:{{todayInfo.count}}/{{todayInfo.wordsLength}}</text>
        </view>
        <view class="center-view">
          <record-circle status="{{status}}" days="{{userInfo.days}}"/>
        </view>
        <view class="bottom-view">
          <button
          text="背单词"
          btn-style='background:#5cb4bd;600cpx'
          c-bind:onclick="judgeUserInfo"
          >  
          </button>
          <view>
            <text class="progress">{{bookInfo.bookName}} {{bookInfo.pass}}/{{bookInfo.bookLength}}</text>
            <progress percent="{{bookInfo.pass/bookInfo.bookLength*100}}"/>
          </view>
          <c-dialog 
            show="{{dialogShow}}"
            type="confirm"
            title="请选择单词书"
            cancel-text="待会"
            confirm-text="去选"
            mask="{{true}}"
            content="您尚未选择单词书,去选一本吧~"
            c-bind:cancel="closeDialog"
            c-bind:confirm="gotoSetting"
            c-bind:close="closeDialog"
            icon-style="{{iconStyle}}"
          >
          </c-dialog>
        </view>
    
        <c-loading loading="{{loading}}"></c-loading>
      </view>
    
    </template>
    
    <script>
    import cml from "chameleon-api";
    import store from "../../store";
    import { GET_INFO, GET_WORDS } from "../../store/action-types";
    class Index {
    	data = {
    		settingImgSrc: require("../../assets/images/setting.png"),
    		dialogShow: false,
    		iconStyle: {
    			 "60cpx",
    			height: "60cpx"
    		},
    		loading: false
    	};
    
    	computed = store.mapState({
    		userInfo: "userInfo",
    		bookInfo: "bookInfo",
    		todayInfo: "todayInfo",
    		status(state) {
    			return state.userInfo.status === "success" ? "success" : "normal";
    		},
    		title(state) {
    			const { todayInfo } = state;
    			const { wordsLength, count } = todayInfo;
    			if (count === 0) {
    				return "今天还没有背单词";
    			} else if (count < wordsLength) {
    				return "今天单词还没有背完";
    			} else {
    				return "今天单词已背完";
    			}
    		}
    	});
    
    	beforeCreate() {
    		cml.setTitle("我思背单词");
    	}
    
    	async mounted() {
    		this.loading = true;
    		await store.dispatch(GET_INFO);
    		this.loading = false;
    	}
    	methods = {
    		judgeUserInfo() {
    			if(this.userInfo.status==="new"){
    				this.dialogShow = true;
    			}else if(this.userInfo.status==="success"){
    				cml.showToast({
    					message: "今天单词已经背完了~",
    					duration: 2000
    				})
    			}else{
    				this.gotoRecite();
    			}
    		},
    		/**
    		 * 单词熟练度规则(初版,待改进)
    		 * 【0】 新词 第一次学习(即times为0)为太简单,直接标记为熟词 7
    		 * 第一次学习为认识,标记熟练度为2;其他情况 学习一轮后熟练度+1
    		 * 【1】 一轮学习后熟练度+1 一次通过再+1
    		 * 【2】 一轮学习后熟练度+1 一次通过再+1
    		 * 【3】 一轮学习后熟练度+1 一次通过再+1
    		 * 【4】 一轮学习数量为2 一次通过熟练度+1
    		 * 【5】 在初始化今日单词的时候熟练度+1并过滤直接加到review
    		 * 【6】 在初始化今日单词的时候熟练度+1并过滤直接加到review
    		 * 【7】 认识:标记为熟词;不认识,熟练度置为4
    		 */
    		async gotoRecite() {
    			this.loading = true;
    			await store.dispatch(GET_WORDS);
    			this.loading = false;
    			return cml.navigateTo({
    				path: "/pages/recite/index"
    			});
    		},
    		gotoSetting() {
    			this.dialogShow = false;
    			cml.navigateTo({
    				path: "/pages/setting/index"
    			});
    		},
    		handleNewUser() {
    			this.dialogShow = true;
    		},
    		closeDialog() {
    			this.dialogShow = false;
    		}
    	};
    }
    
    export default new Index();
    
    </script>
    <style scoped>
      @import './index.css';
    </style>
    <script cml-type="json">
    {
      "base": {
        "usingComponents": {
          "progress": "/components/progress/progress",
          "record-circle": "/components/record-circle/record-circle",
          "c-dialog": "cml-ui/components/c-dialog/c-dialog",
          "c-loading": "cml-ui/components/c-loading/c-loading"
        }
      }
    }
    </script>
    
  • 相关阅读:
    【转】130 个相见恨晚的超实用网站,一次性分享出来
    基于maven testng extentreport git jenkins 持续自动化测试
    TestNG与ExtentReport集成
    Jenkins集成jSonarQube
    SonarQube & Sonar Scanner
    Jenkins集成jacoco收集单元测试覆盖率
    Jenkins集成jacoco收集集成测试覆盖率
    Jacoco收集单元测试、集成测试和系统功能测试覆盖率
    SoanrQube7.4安装(Window)
    SoanrQube使用maven进行代码分析
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10973300.html
Copyright © 2011-2022 走看看