預製卡系統

main
Wayne 3 years ago
parent 64c6e4c2e1
commit 7203d3c46e

@ -0,0 +1,6 @@
VUE_ENV = development
VUE_APP_PUBLIC_PATH = '/admin'
VUE_APP_API_URL=https://card.h888.fun/adminapi/v1

@ -2,5 +2,5 @@ VUE_ENV = production
VUE_APP_PUBLIC_PATH = '/admin'
VUE_APP_API_URL=https://card.h888.fun/adminapi/v1
VUE_APP_API_URL=https://card.slash1000.com/adminapi/v1

@ -6,7 +6,7 @@
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build:dev": "vue-cli-service build --mode development",
"build:h888": "vue-cli-service build --mode development",
"build:sta": "vue-cli-service build --mode stage",
"build:slash": "vue-cli-service build --mode slash",
"lint": "vue-cli-service lint",
@ -18,6 +18,7 @@
},
"dependencies": {
"@antv/data-set": "^0.11.4",
"@vue/composition-api": "^1.7.1",
"animate.css": "^4.1.0",
"ant-design-vue": "1.7.2",
"axios": "^0.19.2",

@ -1,4 +1,5 @@
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
import App from './App.vue'
import {initRouter} from './router'
import './theme/index.less'
@ -26,7 +27,7 @@ Vue.use(Viser)
Vue.use(Plugins)
Vue.use(CKEditor)
Vue.use(VueClipboard)
Vue.use(VueCompositionAPI)
bootstrap({router, store, i18n, message: Vue.prototype.$message})
new Vue({

@ -21,8 +21,8 @@
<a-button @click="handleAddDraw" size="small" type="primary">新增</a-button>
</a-space>
<standard-table :columns="columns" :dataSource="dataSource" :pagination="pagination" @clear="onClear"
@change="onChange" @selectedRowChange="onSelectChange" @showSizeChange="onShowSizeChange"
:scroll="{ x: 1100 }" rowKey="id">
@change="onChange" @selectedRowChange="onSelectChange" @showSizeChange="onShowSizeChange" :scroll="{ x: 1100 }"
rowKey="id">
<div slot="level" slot-scope="row">
{{ level[row.text] }}
</div>
@ -37,16 +37,13 @@
</div>
<div slot="action" slot-scope="{text, record}">
<a class="edit-btn" style="margin-right: 8px" @click="doCopy(text.nfcurl)"
v-show="record.verify_code.length > 0">
<a class="edit-btn" style="margin-right: 8px" @click="doCopy(text.nfcurl)">
<a-icon type="edit" />複製URL
</a>
<a class="edit-btn" download style="margin-right: 8px" @click="downloadQr(text)"
v-show="record.verify_code.length > 0">
<a class="edit-btn" download style="margin-right: 8px" @click="downloadQr(text)">
<a-icon type="edit" />下載QR
</a>
<a class="edit-btn" style="margin-right: 8px" v-show="record.verify_code.length > 0" v-print="printObj"
@click="printQr(text)">
<a class="edit-btn" style="margin-right: 8px" v-print="printObj" @click="printQr(text)">
<a-icon type="edit" />列印
</a>
<a class="delete-btn" @click="deleteCard(record.id)">
@ -64,15 +61,13 @@
<div id="qrcode" ref="qrcode"></div>
</div>
</div>
<a-modal title="片讀碼" :width="350" :visible="showCodeScan" @cancel="handleCancel" :destroyOnClose="true"
<a-modal title="NFC製卡" :width="350" :visible="showCodeScan" @cancel="handleCancel" :destroyOnClose="true"
:footer="null" :afterClose="closeModal">
<div class="vcard-img" @click="handleFocus">
<img width="150" src="@/assets/images/applepay.gif">
</div>
<div :class="{ 'vcode-input-error': !vcodeStatus, 'vcode-input-info': vcodeStatus }">
<a-input v-model="vcode.code" type="password" autocomplete="off" ref="vcode" @keyup.enter="getVCode"
@blur="handleVCodeBlur"></a-input>
<a-input :value="vcodeMsg" type="text" @focus="handleFocus" style="top:-32px;"></a-input>
<a-input :value="vcodeMsg" type="text" style="top:-32px;"></a-input>
</div>
</a-modal>
</div>
@ -103,9 +98,9 @@ const columns = [
},
{
title: '代理',
dataIndex: 'agent_name',
key: 'agent_name',
title: '名稱',
dataIndex: 'name',
key: 'name',
width: 120
},
// {
@ -116,7 +111,7 @@ const columns = [
// },
{
title: '卡號',
dataIndex: 'verify_code',
dataIndex: 'serial_no',
width: 100
},
{
@ -255,16 +250,10 @@ export default {
},
async onSwitchChange(checked, rec) {
this.showCodeScan = true
this.vcode.id = rec.id
this.$nextTick(function () {
this.vcodeMsg = '請將卡片靠近讀卡機'
this.vcodeStatus = true
this.$refs.vcode.select()
})
if (checked === true) {
this.getVCode(rec.id)
}
return
},
onShowSizeChange(current, size) {
this.pagination.current = current
@ -340,6 +329,7 @@ export default {
console.log(this.vcode)
},
//
handleFocus() {
this.vcodeMsg = '請將卡片靠近讀卡機'
this.vcodeStatus = true
@ -349,42 +339,84 @@ export default {
this.vcodeMsg = '點擊此處開始偵測感應'
this.vcodeStatus = false
},
async getVCode() {
if (this.vcode.code.trim().length != 8 && this.vcode.code.trim().length != 14) {
this.vcode.code = ''
this.vcodeMsg = '掃碼失敗'
async getVCode(id) {
let nfcReaderUrl = 'http://localhost:8088'
this.showCodeScan = true
this.vcode.id = id
this.vcodeStatus = true
this.vcodeMsg = '請將卡片靠近讀卡機'
let res1 = await fetch(nfcReaderUrl + '/getnfcid', {
method: 'GET',
})
res1 = await res1.json()
if (res1.code !== 200) {
this.vcodeMsg = res1.error
this.vcodeStatus = false
setTimeout(() => {
this.vcodeMsg = '請將卡片靠近讀卡機'
this.vcodeStatus = true
this.showCodeScan = false
return this.$message.success('操作失敗')
}, 2000)
return
}
this.vcode.code = this.vcode.code.toUpperCase()
this.vcodeMsg = '讀取卡號' + res1.sid
this.vcode.code = res1.sid
const res = await updateVerifyCode(
let res2 = await updateVerifyCode(
this.vcode
)
this.vcode.code = ''
if (res.code !== 200) {
// return this.$message.error(res.data);
this.vcodeMsg = res.data
if (res2.code !== 200) {
this.vcodeMsg = res2.data
this.vcodeStatus = false
setTimeout(() => {
this.vcodeStatus = true
this.vcodeMsg = '請將卡片靠近讀卡機'
this.showCodeScan = false
return this.$message.success('操作失敗')
}, 2000)
return
}
this.vcodeMsg = '開始寫入卡片...'
const data = new URLSearchParams();
data.append('data', res2.data);
let res3 = await fetch(nfcReaderUrl + '/writenfc', {
method: 'POST',
body: data,
})
res3 = await res3.json()
if (res3.code !== 200) {
this.vcodeMsg = res3.error
this.vcodeStatus = false
setTimeout(() => {
this.showCodeScan = false
return this.$message.success('操作失敗')
}, 2000)
return
}
this.vcodeMsg = '寫入成功'
this.vcodeStatus = true
this.vcode.code = ''
this.vcode.id = null
this.genTable()
setTimeout(() => {
this.showCodeScan = false
return this.$message.success('操作成功')
}, 2000)
},
closeModal() {
this.vcode = { id: null, code: '' }

@ -1,34 +1,36 @@
<template>
<div>
<a-drawer
title="新增預製卡"
:destroyOnClose="true"
:visible="visible"
:body-style="{ paddingBottom: '80px' }"
@close="onClose"
>
<a-form-model
ref="ruleForm"
:model="form"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-form-model-item label="數量"
:rules="{
<a-drawer title="新增預製卡" :destroyOnClose="true" :visible="visible" :body-style="{ paddingBottom: '80px' }"
@close="onClose">
<a-form-model ref="ruleForm" :model="form" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-model-item label="名稱" prop="name" :rules="{
required: true,
message: '必填',
trigger: 'blur',
}"
>
}">
<a-input v-model="form.name" />
</a-form-model-item>
<a-form-model-item label="數量" prop="number" :rules="{
required: true,
message: '必填',
trigger: 'blur',
}">
<a-input v-model="form.number" />
</a-form-model-item>
<a-form-model-item label="代理" ref="agent" prop="agent">
<a-form-model-item label="使用天數" prop="days" :rules="{
required: true,
message: '必填',
trigger: 'blur',
}">
<a-input v-model="form.days" />
</a-form-model-item>
<!-- <a-form-model-item label="代理" ref="agent" prop="agent">
<a-select v-model="form.agent_id" placeholder="請選擇">
<a-select-option :value="v.id" v-for="v of agentList" :key="v.id">
{{v.name}}
</a-select-option>
</a-select>
</a-form-model-item>
</a-form-model-item> -->
<a-form-model-item label="開卡到期日" prop="expire">
<a-date-picker @change="onChange" :value="expire" />
</a-form-model-item>
@ -38,8 +40,7 @@
</a-form-model-item> -->
</a-form-model>
<div
:style="{
<div :style="{
position: 'absolute',
right: 0,
bottom: 0,
@ -49,8 +50,7 @@
background: '#fff',
textAlign: 'right',
zIndex: 1,
}"
>
}">
<a-button :style="{ marginRight: '8px' }" @click="onClose">
關閉
</a-button>
@ -77,8 +77,9 @@ export default {
wrapperCol: { span: 16 },
roleList: [],
form: {
number: 1,
agent_id: null,
name: '',
number: null,
days: null,
expire_time: null
},
rules: {
@ -137,12 +138,13 @@ export default {
<style lang="less" scoped>
.ant-drawer-header {
background-color: #87e8de !important;
.ant-drawer-title {
color: #FFF !important;
}
}
.ant-drawer-content-wrapper {
width: 50% !important;
}
</style>

@ -1,7 +1,5 @@
import {request, ajax, METHOD} from '@/utils/request'
export function addPrecard(params){
return ajax('/card/addPrecard', params, 'post')
}

@ -1351,6 +1351,11 @@
optionalDependencies:
"prettier" "^1.18.2"
"@vue/composition-api@^1.7.1":
"integrity" "sha512-xDWoEtxGXhH9Ku3ROYX/rzhcpt4v31hpPU5zF3UeVC/qxA3dChmqU8zvTUYoKh3j7rzpNsoFOwqsWG7XPMlaFA=="
"resolved" "https://registry.npmjs.org/@vue/composition-api/-/composition-api-1.7.1.tgz"
"version" "1.7.1"
"@vue/preload-webpack-plugin@^1.1.0":
"integrity" "sha1-GHI1MNME9EMCHaIpLW7JUCgmEEo="
"resolved" "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.1.tgz"
@ -2312,7 +2317,7 @@
"fill-range" "^7.0.1"
"brorand@^1.0.1":
"integrity" "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w=="
"integrity" "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w=="
"resolved" "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz"
"version" "1.1.0"
@ -5104,7 +5109,7 @@
"slash" "^2.0.0"
"good-listener@^1.2.2":
"integrity" "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA= sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw=="
"integrity" "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw== sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw=="
"resolved" "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz"
"version" "1.2.2"
dependencies:
@ -5288,7 +5293,7 @@
"version" "9.18.1"
"hmac-drbg@^1.0.0":
"integrity" "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg=="
"integrity" "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg=="
"resolved" "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz"
"version" "1.0.1"
dependencies:
@ -5514,7 +5519,7 @@
"version" "3.3.0"
"import-cwd@^2.0.0":
"integrity" "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg=="
"integrity" "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg== sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg=="
"resolved" "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz"
"version" "2.1.0"
dependencies:
@ -5545,7 +5550,7 @@
"resolve-from" "^4.0.0"
"import-from@^2.1.0":
"integrity" "sha1-M1238qev/VOqpHHUuAId7ja387E= sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w=="
"integrity" "sha1-M1238qev/VOqpHHUuAId7ja387E=sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w== sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w=="
"resolved" "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz"
"version" "2.1.0"
dependencies:
@ -6800,7 +6805,7 @@
"version" "1.0.1"
"minimalistic-crypto-utils@^1.0.0", "minimalistic-crypto-utils@^1.0.1":
"integrity" "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="
"integrity" "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="
"resolved" "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz"
"version" "1.0.1"
@ -8244,7 +8249,7 @@
"version" "1.5.1"
"qrcodejs2@^0.0.2":
"integrity" "sha1-Rlr+Xjnxn6zsuTLBH3oYYQkUauE= sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA=="
"integrity" "sha1-Rlr+Xjnxn6zsuTLBH3oYYQkUauE=sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA== sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA=="
"resolved" "https://registry.npmjs.org/qrcodejs2/-/qrcodejs2-0.0.2.tgz"
"version" "0.0.2"
@ -8824,7 +8829,7 @@
"version" "2.0.0"
"select@^1.1.2":
"integrity" "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA=="
"integrity" "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA== sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA=="
"resolved" "https://registry.npmjs.org/select/-/select-1.1.2.tgz"
"version" "1.1.2"
@ -10384,7 +10389,7 @@
"resolved" "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz"
"version" "1.9.1"
"vue@^2.0.0", "vue@^2.2.6", "vue@^2.5.17", "vue@^2.5.2", "vue@^2.5.3", "vue@^2.6.10", "vue@^2.6.11", "vue@>=2.5.0", "vue@>=2.6.0":
"vue@^2.0.0", "vue@^2.2.6", "vue@^2.5.17", "vue@^2.5.2", "vue@^2.5.3", "vue@^2.6.10", "vue@^2.6.11", "vue@>= 2.5 < 2.7", "vue@>=2.5.0", "vue@>=2.6.0":
"integrity" "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ=="
"resolved" "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz"
"version" "2.6.14"

Loading…
Cancel
Save