b5a6a2b7 by zhangyongfeng

增加照片导入功能

1 parent fea180bf
...@@ -19,3 +19,4 @@ yarn-error.log* ...@@ -19,3 +19,4 @@ yarn-error.log*
19 *.njsproj 19 *.njsproj
20 *.sln 20 *.sln
21 *.sw? 21 *.sw?
22 config.js
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
21 }" 21 }"
22 > 22 >
23 {{ item.name ? item.name : item.key }} 23 {{ item.name ? item.name : item.key }}
24 <img v-if="item.photo" :src="item.photo" :width="50" :height="50" />
24 </a> 25 </a>
25 </li> 26 </li>
26 </ul> 27 </ul>
...@@ -34,26 +35,17 @@ ...@@ -34,26 +35,17 @@
34 :key="item" 35 :key="item"
35 class="itemres" 36 class="itemres"
36 :style="resCardStyle" 37 :style="resCardStyle"
38 :data-id="item"
37 @click="showRes = false" 39 @click="showRes = false"
38 > 40 >
39 <span 41 <span
40 class="key"
41 :style="{
42 fontSize: list[item - 1] && list[item - 1].name ? '36px' : null,
43 lineHeight:
44 list[item - 1] && list[item - 1].name ? '80px' : null
45 }"
46 v-if="list[item - 1] && list[item - 1].name"
47 >
48 {{ item }}
49 </span>
50 <span
51 class="cont" 42 class="cont"
52 :style="{ 43 :style="{
53 fontSize: list[item - 1] && list[item - 1].name ? '36px' : null, 44 fontSize: list[item - 1] && list[item - 1].name ? '36px' : null,
54 lineHeight: 45 lineHeight:
55 list[item - 1] && list[item - 1].name ? '80px' : null 46 list[item - 1] && list[item - 1].name ? '80px' : null
56 }" 47 }"
48 v-if="!photos.find(d => d.id === item)"
57 > 49 >
58 <span v-if="list[item - 1] && list[item - 1].name"> 50 <span v-if="list[item - 1] && list[item - 1].name">
59 {{ list[item - 1].name }} 51 {{ list[item - 1].name }}
...@@ -62,6 +54,13 @@ ...@@ -62,6 +54,13 @@
62 {{ item }} 54 {{ item }}
63 </span> 55 </span>
64 </span> 56 </span>
57 <img
58 v-if="photos.find(d => d.id === item)"
59 :src="photos.find(d => d.id === item).value"
60 alt="photo"
61 :width="160"
62 :height="160"
63 />
65 </span> 64 </span>
66 </div> 65 </div>
67 </div> 66 </div>
...@@ -71,6 +70,7 @@ ...@@ -71,6 +70,7 @@
71 <Tool 70 <Tool
72 @toggle="toggle" 71 @toggle="toggle"
73 @resetConfig="reloadTagCanvas" 72 @resetConfig="reloadTagCanvas"
73 @getPhoto="getPhoto"
74 :running="running" 74 :running="running"
75 :closeRes="closeRes" 75 :closeRes="closeRes"
76 /> 76 />
...@@ -95,6 +95,7 @@ import { ...@@ -95,6 +95,7 @@ import {
95 } from '@/helper/index'; 95 } from '@/helper/index';
96 import { luckydrawHandler } from '@/helper/algorithm'; 96 import { luckydrawHandler } from '@/helper/algorithm';
97 import Result from '@/components/Result'; 97 import Result from '@/components/Result';
98 import { database, DB_STORE_NAME } from '@/helper/db';
98 export default { 99 export default {
99 name: 'App', 100 name: 'App',
100 101
...@@ -143,15 +144,20 @@ export default { ...@@ -143,15 +144,20 @@ export default {
143 const datas = []; 144 const datas = [];
144 for (let index = 1; index <= this.config.number; index++) { 145 for (let index = 1; index <= this.config.number; index++) {
145 const listData = this.list.find(d => d.key === index); 146 const listData = this.list.find(d => d.key === index);
147 const photo = this.photos.find(d => d.id === index);
146 datas.push({ 148 datas.push({
147 key: index, 149 key: index,
148 name: listData ? listData.name : '' 150 name: listData ? listData.name : '',
151 photo: photo ? photo.value : ''
149 }); 152 });
150 } 153 }
151 return datas; 154 return datas;
152 }, 155 },
153 categoryName() { 156 categoryName() {
154 return conversionCategoryName(this.category); 157 return conversionCategoryName(this.category);
158 },
159 photos() {
160 return this.$store.state.photos;
155 } 161 }
156 }, 162 },
157 created() { 163 created() {
...@@ -192,10 +198,30 @@ export default { ...@@ -192,10 +198,30 @@ export default {
192 category: '' 198 category: ''
193 }; 199 };
194 }, 200 },
201 watch: {
202 photos: {
203 deep: true,
204 handler() {
205 this.$nextTick(() => {
206 this.reloadTagCanvas();
207 });
208 }
209 }
210 },
195 mounted() { 211 mounted() {
196 this.startTagCanvas(); 212 this.startTagCanvas();
213 setTimeout(() => {
214 this.getPhoto();
215 }, 1000);
197 }, 216 },
198 methods: { 217 methods: {
218 getPhoto() {
219 database.getAll(DB_STORE_NAME).then(res => {
220 if (res && res.length > 0) {
221 this.$store.commit('setPhotos', res);
222 }
223 });
224 },
199 speed() { 225 speed() {
200 return [0.1 * Math.random() + 0.01, -(0.1 * Math.random() + 0.01)]; 226 return [0.1 * Math.random() + 0.01, -(0.1 * Math.random() + 0.01)];
201 }, 227 },
...@@ -323,7 +349,7 @@ export default { ...@@ -323,7 +349,7 @@ export default {
323 position: absolute; 349 position: absolute;
324 top: 50%; 350 top: 50%;
325 left: 50%; 351 left: 50%;
326 width: 1000px; 352 width: 1280px;
327 transform: translateX(-50%) translateY(-50%); 353 transform: translateX(-50%) translateY(-50%);
328 text-align: center; 354 text-align: center;
329 p { 355 p {
...@@ -345,15 +371,29 @@ export default { ...@@ -345,15 +371,29 @@ export default {
345 line-height: 160px; 371 line-height: 160px;
346 font-weight: bold; 372 font-weight: bold;
347 margin-right: 20px; 373 margin-right: 20px;
348 margin-top: 20px; 374 margin-top: 70px;
349 cursor: pointer; 375 cursor: pointer;
350 display: flex; 376 display: flex;
351 flex-direction: column; 377 flex-direction: column;
352 align-items: center; 378 align-items: center;
353 justify-content: center; 379 justify-content: center;
380 position: relative;
354 .key { 381 .key {
355 color: red; 382 color: red;
356 } 383 }
384 &::before {
385 content: attr(data-id);
386 width: 70px;
387 height: 50px;
388 background-color: #fff;
389 position: absolute;
390 top: -50px;
391 left: 50%;
392 transform: translateX(-50%);
393 font-size: 30px;
394 line-height: 50px;
395 border-radius: 50%;
396 }
357 } 397 }
358 } 398 }
359 </style> 399 </style>
......
1 <template>
2 <el-dialog
3 :visible="visible"
4 :append-to-body="true"
5 width="300px"
6 @close="$emit('update:visible', false)"
7 class="c-Importphoto"
8 >
9 <el-row>
10 <label for="idinput">抽奖号码</label>
11 <el-input
12 id="idinput"
13 size="mini"
14 type="number"
15 v-model="id"
16 :min="0"
17 :max="config.number"
18 ></el-input>
19 </el-row>
20 <el-row>
21 <label for="idinput">照片选择</label>
22 <span class="selectbg" :data-tip="filename">
23 <input
24 ref="uploadinput"
25 class="upload"
26 type="file"
27 accept=".jpg,.png"
28 @change="inputChange"
29 />
30 </span>
31 </el-row>
32 <el-row class="photo">
33 <label>已选照片</label>
34 <img v-if="value" :src="value" alt="img" :width="140" :height="140" />
35 <span v-else>暂未选择</span>
36 </el-row>
37 <el-row class="center">
38 <el-button size="mini" type="primary" @click="saveHandler"
39 >保存</el-button
40 >
41 <el-button size="mini" @click="$emit('update:visible', false)"
42 >取消</el-button
43 >
44 </el-row>
45 </el-dialog>
46 </template>
47 <script>
48 import { database, DB_STORE_NAME } from '@/helper/db';
49
50 export default {
51 name: 'Importphoto',
52 props: {
53 visible: Boolean
54 },
55 computed: {
56 config: {
57 get() {
58 return this.$store.state.config;
59 }
60 }
61 },
62 data() {
63 return {
64 id: 0,
65 value: '',
66 filename: '点击选择照片'
67 };
68 },
69 methods: {
70 inputChange(e) {
71 const fileList = e.target.files;
72 const formData = new FormData();
73 formData.append('uploadImg', fileList[0]);
74 const reader = new FileReader();
75 const AllowImgFileSize = 1024 * 1024;
76 const file = fileList[0];
77 if (file) {
78 this.filename = file.name;
79 reader.readAsDataURL(file);
80 reader.onload = () => {
81 if (
82 AllowImgFileSize != 0 &&
83 AllowImgFileSize < reader.result.length
84 ) {
85 return this.$message.error('不允许上传大于1M的图片');
86 } else {
87 this.value = reader.result;
88 }
89 };
90 }
91 },
92 async saveHandler() {
93 const { id, value } = this;
94 const ID = Number(id);
95 if (!ID || ID <= 0) {
96 return this.$message.error('号码必须大于0的整数');
97 }
98 if (!value) {
99 return this.$message.error('请选择照片');
100 }
101 const Data = await database.get(DB_STORE_NAME, ID);
102 const param = {
103 id: ID,
104 value
105 };
106 database[Data ? 'edit' : 'add'](
107 DB_STORE_NAME,
108 Data ? ID : param,
109 Data ? param : null
110 )
111 .then(res => {
112 if (res) {
113 this.$refs.uploadinput.value = '';
114 this.value = '';
115 this.filename = '点击选择照片';
116 this.$emit('update:visible', false);
117 this.$emit('getPhoto');
118 this.$message({
119 message: '保存成功',
120 type: 'success'
121 });
122 } else {
123 this.$message.error('保存失败');
124 }
125 })
126 .catch(err => {
127 this.$message.error(err.message);
128 });
129 }
130 }
131 };
132 </script>
133 <style lang="scss">
134 .c-Importphoto {
135 .el-dialog {
136 height: 330px;
137 }
138 label {
139 margin-right: 20px;
140 vertical-align: top;
141 }
142 .el-input {
143 width: 140px;
144 }
145 .el-row {
146 padding: 5px 0;
147 }
148 .center {
149 text-align: center;
150 }
151 .selectbg {
152 display: inline-block;
153 border: 1px solid #ccc;
154 border-radius: 2px;
155 width: 140px;
156 height: 28px;
157 position: relative;
158 box-sizing: border-box;
159 &::before {
160 content: attr(data-tip);
161 width: 100%;
162 height: 100%;
163 text-align: center;
164 position: absolute;
165 top: 0;
166 left: 0;
167 line-height: 28px;
168 cursor: pointer;
169 overflow: hidden;
170 font-size: 12px;
171 }
172 .upload {
173 position: absolute;
174 top: 0;
175 left: 0;
176 width: 100%;
177 height: 100%;
178 opacity: 0;
179 z-index: 10;
180 cursor: pointer;
181 }
182 }
183 .photo {
184 img {
185 border: 1px solid #ccc;
186 }
187 span {
188 display: inline-block;
189 border: 1px solid #ccc;
190 border-radius: 2px;
191 width: 140px;
192 height: 140px;
193 line-height: 140px;
194 text-align: center;
195 position: relative;
196 box-sizing: border-box;
197 }
198 }
199 }
200 </style>
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
9 <el-button size="mini" @click="showImport = true"> 9 <el-button size="mini" @click="showImport = true">
10 导入名单 10 导入名单
11 </el-button> 11 </el-button>
12 <el-button size="mini" @click="showImportphoto = true">
13 导入照片
14 </el-button>
12 <el-dialog 15 <el-dialog
13 :append-to-body="true" 16 :append-to-body="true"
14 :visible.sync="showSetwat" 17 :visible.sync="showSetwat"
...@@ -97,11 +100,17 @@ ...@@ -97,11 +100,17 @@
97 <el-button size="mini" @click="showImport = false">取消</el-button> 100 <el-button size="mini" @click="showImport = false">取消</el-button>
98 </div> 101 </div>
99 </el-dialog> 102 </el-dialog>
103 <Importphoto
104 :visible.sync="showImportphoto"
105 @getPhoto="$emit('getPhoto')"
106 ></Importphoto>
100 </div> 107 </div>
101 </template> 108 </template>
102 109
103 <script> 110 <script>
104 import { clearData, conversionCategoryName } from '@/helper/index'; 111 import { clearData, conversionCategoryName } from '@/helper/index';
112 import Importphoto from './Importphoto';
113 import { database, DB_STORE_NAME } from '@/helper/db';
105 114
106 export default { 115 export default {
107 props: { 116 props: {
...@@ -143,10 +152,12 @@ export default { ...@@ -143,10 +152,12 @@ export default {
143 return options; 152 return options;
144 } 153 }
145 }, 154 },
155 components: { Importphoto },
146 data() { 156 data() {
147 return { 157 return {
148 showSetwat: false, 158 showSetwat: false,
149 showImport: false, 159 showImport: false,
160 showImportphoto: false,
150 form: { 161 form: {
151 category: '', 162 category: '',
152 mode: 1, 163 mode: 1,
...@@ -166,6 +177,7 @@ export default { ...@@ -166,6 +177,7 @@ export default {
166 .then(() => { 177 .then(() => {
167 clearData(); 178 clearData();
168 this.$store.commit('setClearStore'); 179 this.$store.commit('setClearStore');
180 database.clear(DB_STORE_NAME);
169 this.closeRes && this.closeRes(); 181 this.closeRes && this.closeRes();
170 this.$message({ 182 this.$message({
171 type: 'success', 183 type: 'success',
......
1 const DB_STORE_NAME = 'luckydraw.GuaranteeTransaction';
2 let objectStore;
3 const createObjectStore = db => {
4 objectStore = db.createObjectStore(DB_STORE_NAME, {
5 keyPath: 'id',
6 autoIncrement: true
7 });
8 objectStore.createIndex('id', 'id', {
9 unique: true
10 });
11 objectStore.createIndex('name', 'name');
12 };
13
14 const createObjectStoreOrder = db => {
15 if (!db.objectStoreNames.contains(DB_STORE_NAME)) {
16 createObjectStore(db);
17 } else {
18 db.deleteObjectStore(DB_STORE_NAME);
19 createObjectStore(db);
20 }
21 };
22
23 const DBVERSION = 1;
24 const DBNAME = 'luckydraw';
25 // 数据库:IDBDatabase 对象
26 // 对象仓库:IDBObjectStore 对象
27 // 索引: IDBIndex 对象
28 // 事务: IDBTransaction 对象
29 // 操作请求:IDBRequest 对象
30 // 指针: IDBCursor 对象
31 // 主键集合:IDBKeyRange 对象
32 let db;
33 class LuckydrawIndecDB {
34 constructor() {
35 this.InitIndexedDB();
36 }
37 add = (TableName, newItem) => {
38 const addInfo = {
39 createdTime: Date.now(),
40 updateTime: Date.now()
41 };
42 return new Promise((resolve, reject) => {
43 const transaction = db.transaction([TableName], 'readwrite');
44 const objectStore = transaction.objectStore(TableName);
45 const objectStoreRequest = objectStore.add(
46 Object.assign({}, addInfo, newItem)
47 );
48 objectStoreRequest.onsuccess = () => {
49 resolve(true);
50 };
51 objectStoreRequest.onerror = error => {
52 reject(error.target.error);
53 };
54 });
55 };
56 edit = (TableName, id, data) => {
57 const editInfo = {
58 updateTime: Date.now()
59 };
60 return new Promise((resolve, reject) => {
61 const transaction = db.transaction([TableName], 'readwrite');
62 const objectStore = transaction.objectStore(TableName);
63 const objectStoreRequest = objectStore.get(id);
64 objectStoreRequest.onsuccess = () => {
65 const myRecord = objectStoreRequest.result;
66 for (const key in data) {
67 if (typeof myRecord[key] !== 'undefined') {
68 myRecord[key] = data[key];
69 }
70 }
71 const objectStoreRequestGetRes = objectStore.put(
72 Object.assign({}, myRecord, editInfo)
73 );
74 objectStoreRequestGetRes.onsuccess = () => {
75 resolve(true);
76 };
77 objectStoreRequestGetRes.onerror = error => {
78 reject(error);
79 };
80 };
81 });
82 };
83 del = (TableName, id) => {
84 return new Promise((resolve, reject) => {
85 const objectStore = db
86 .transaction([TableName], 'readwrite')
87 .objectStore(TableName);
88 const objectStoreRequest = objectStore.delete(id);
89 objectStoreRequest.onsuccess = () => {
90 resolve(true);
91 };
92 objectStoreRequest.onerror = error => {
93 reject(error);
94 };
95 });
96 };
97
98 clear = TableName => {
99 return new Promise((resolve, reject) => {
100 const objectStore = db
101 .transaction([TableName], 'readwrite')
102 .objectStore(TableName);
103 const objectStoreRequest = objectStore.clear();
104 objectStoreRequest.onsuccess = () => {
105 resolve(true);
106 };
107 objectStoreRequest.onerror = error => {
108 reject(error);
109 };
110 });
111 };
112
113 count = TableName => {
114 return new Promise((resolve, reject) => {
115 const objectStore = db
116 .transaction([TableName], 'readwrite')
117 .objectStore(TableName);
118 const objectStoreRequest = objectStore.count();
119 objectStoreRequest.onsuccess = () => {
120 resolve(objectStoreRequest.result);
121 };
122 objectStoreRequest.onerror = error => {
123 reject(error);
124 };
125 });
126 };
127
128 get = (TableName, id) => {
129 return new Promise((resolve, reject) => {
130 const objectStore = db.transaction(TableName).objectStore(TableName);
131 const objectStoreRequest = objectStore.get(id);
132 objectStoreRequest.onsuccess = () => {
133 resolve(objectStoreRequest.result);
134 };
135 objectStoreRequest.onerror = error => {
136 reject(error);
137 };
138 });
139 };
140
141 getKey = (TableName, key) => {
142 return new Promise((resolve, reject) => {
143 const objectStore = db.transaction(TableName).objectStore(TableName);
144 const objectStoreRequest = objectStore.getKey(key);
145 objectStoreRequest.onsuccess = () => {
146 resolve(objectStoreRequest.result);
147 };
148 objectStoreRequest.onerror = error => {
149 reject(error);
150 };
151 });
152 };
153
154 getAll = TableName => {
155 return new Promise((resolve, reject) => {
156 const objectStore = db.transaction(TableName).objectStore(TableName);
157 const objectStoreRequest = objectStore.getAll();
158 objectStoreRequest.onsuccess = () => {
159 resolve(objectStoreRequest.result);
160 };
161 objectStoreRequest.onerror = error => {
162 reject(error);
163 };
164 });
165 };
166
167 onerror = event => {
168 console.log('db-connection-fail', event);
169 };
170 InitIndexedDB = () => {
171 const DBOpenRequest = window.indexedDB.open(DBNAME, DBVERSION);
172 // 数据库打开失败
173 DBOpenRequest.onerror = event => {
174 this.onerror(event);
175 };
176
177 DBOpenRequest.onsuccess = () => {
178 // 存储数据结果
179 db = DBOpenRequest.result;
180 console.log('db-connection-success');
181 };
182
183 DBOpenRequest.onupgradeneeded = () => {
184 db = event.target.result;
185 createObjectStoreOrder(db);
186 };
187 };
188 }
189
190 const database = new LuckydrawIndecDB();
191
192 export { LuckydrawIndecDB, database, DB_STORE_NAME };
...@@ -37,7 +37,6 @@ export const configField = 'config'; // 配置数据 ...@@ -37,7 +37,6 @@ export const configField = 'config'; // 配置数据
37 export const resultField = 'result'; // 抽奖结果 37 export const resultField = 'result'; // 抽奖结果
38 export const newLotteryField = 'newLottery'; // 新增奖项 38 export const newLotteryField = 'newLottery'; // 新增奖项
39 export const listField = 'list'; // 名单 39 export const listField = 'list'; // 名单
40
41 export function conversionCategoryName(key) { 40 export function conversionCategoryName(key) {
42 let name = ''; 41 let name = '';
43 switch (key) { 42 switch (key) {
......
...@@ -30,7 +30,8 @@ export default new Vuex.Store({ ...@@ -30,7 +30,8 @@ export default new Vuex.Store({
30 fifthPrize: [] 30 fifthPrize: []
31 }, 31 },
32 newLottery: [], 32 newLottery: [],
33 list: [] 33 list: [],
34 photos: []
34 }, 35 },
35 mutations: { 36 mutations: {
36 setClearStore(state) { 37 setClearStore(state) {
...@@ -54,6 +55,7 @@ export default new Vuex.Store({ ...@@ -54,6 +55,7 @@ export default new Vuex.Store({
54 }; 55 };
55 state.newLottery = []; 56 state.newLottery = [];
56 state.list = []; 57 state.list = [];
58 state.photos = [];
57 }, 59 },
58 setConfig(state, config) { 60 setConfig(state, config) {
59 state.config = config; 61 state.config = config;
...@@ -83,6 +85,9 @@ export default new Vuex.Store({ ...@@ -83,6 +85,9 @@ export default new Vuex.Store({
83 state.list = arr; 85 state.list = arr;
84 86
85 setData(listField, arr); 87 setData(listField, arr);
88 },
89 setPhotos(state, photos) {
90 state.photos = photos;
86 } 91 }
87 }, 92 },
88 actions: {}, 93 actions: {},
......