Commit c01eed3b authored by zL's avatar zL

提交部分代码

parent 546560c2
This diff is collapsed.
...@@ -7,11 +7,13 @@ ...@@ -7,11 +7,13 @@
}, },
"dependencies": { "dependencies": {
"@types/js-md5": "^0.4.2", "@types/js-md5": "^0.4.2",
"@types/qrcode": "^1.3.5",
"axios": "^0.18.0", "axios": "^0.18.0",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
"element-ui": "^2.13.2", "element-ui": "^2.13.2",
"js-md5": "^0.7.3", "js-md5": "^0.7.3",
"qrcode": "^1.4.4",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-class-component": "^7.2.3", "vue-class-component": "^7.2.3",
"vue-property-decorator": "^8.4.2", "vue-property-decorator": "^8.4.2",
......
<template>
<div class="common_dialog" :class="{'t_mask': showMask,'t_mask2':showMask2}" @click="ClickingBackground">
<div class="dialog_content">
<i class="iconfont iconjiufuqianbaoicon08" v-if="!close" @click.stop="closePopup"></i>
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
@Component
export default class CommonDialog extends Vue {
@Prop({ type: Boolean, default: false }) showMask!: boolean;
@Prop({ type: Boolean, default: false }) showMask2!: boolean;
@Prop({ type: Boolean, default: false }) close!: boolean;
/**
* name
*/
public ClickingBackground() {
// console.log("关闭当前弹窗");
this.$emit("ClickingBackground");
}
public closePopup() {
// console.log("关闭当前弹窗");
this.$emit("closePopup");
}
}
</script>
<style scoped lang="less">
.common_dialog {
z-index: 99; /* 最高 */
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
text-align: center;
}
.t_mask {
background: rgba(0, 0, 0, 0.1);
}
.t_mask2{
background-color: rgba(55, 55, 55, 0.6);
}
.dialog_content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
text-align: left;
background: #fff;
box-shadow: 0 0 20px 0 rgba(61, 118, 249, 0.18);
max-height: 80vh;
.iconjiufuqianbaoicon08 {
position: absolute;
top: -30px;
font-size: 28px;
cursor: pointer;
right: -30px;
color: rgba(0, 0, 0, 0.4);
}
}
</style>
<template>
<div class="dialog_input">
<input
:value="value"
type="text"
class="input"
:class="{'js-input_error':errorShowing&&value.length===0}"
@input="handleInput"
v-bind="$attrs"
maxlength="10"
/>
<slot></slot>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
@Component
export default class DialogInput extends Vue {
@Prop({ type: String, required: true }) value!: string;
@Prop({ type: Boolean, default: false }) errorShowing!: boolean; // 当前显示错误 todo 改为sync
public handleInput(e: any) {
const val = e.target.value;
this.$emit("input", val);
}
}
</script>
<style scoped>
.dialog_input {
display: inline-block;
}
.input {
box-sizing: border-box;
padding: 0 26px;
width: 500px;
height: 44px;
border: 1px solid #e2e2e2;
outline: none;
font-size: 18px;
color: #797d84;
}
.js-input_error {
border: 1px solid rgba(208, 2, 27, 0.5);
}
.input::placeholder {
color: #c0c6d2;
}
</style>
<template>
<div class="pagination">
<div class="btn_nav" :class="{'js-btn_nav_disable':value===1}" @click="navLeft">
<i class="iconfont iconyidong btn_nav-icon btn_nav-icon_right"></i>
</div>
<span class="item_box" :class="{'js-item_box_active':value===1}" @click="changePage(1)">1</span>
<span v-if="mid[0]&&mid[0]>2" class="item_box">...</span>
<span v-for="item in mid"
class="item_box"
:class="{'js-item_box_active':value===item}"
:key="item"
@click="changePage(item)">{{item}}</span>
<span v-if="mid.length>4&&mid[mid.length-1]<pageCount-1" class="item_box">...</span>
<span class="item_box" v-if="pageCount>1" :class="{'js-item_box_active':value===pageCount}"
@click="changePage(pageCount)">{{pageCount}}</span>
<div class="btn_nav btn_nav_right" :class="{'js-btn_nav_disable':value===pageCount}" @click="navRight">
<i class="iconfont iconyidong btn_nav-icon"></i>
</div>
<slot></slot>
</div>
</template>
<script lang="ts">
import {Component, Prop, Vue} from 'vue-property-decorator';
/**
* 分页组件
* @author yuanzeyu
* @date 2019-05-30
* @desc @change
*/
@Component
export default class Pagination extends Vue {
@Prop({type: Number, required: true}) value!: number; // 从1开始
@Prop({type: Number, required: true}) total!: number;
@Prop({type: Number, default: 10}) size!: number;
public get pageCount() {
return Math.ceil(this.total / this.size);
}
public get mid() {
const arr = Array.from({length: this.pageCount}, (value, key) => key + 1);
if (this.pageCount < 7) {
return arr.slice(1, this.pageCount - 1);
}
if (this.value < 4) {
return arr.splice(1, 5);
}
if (this.value > this.pageCount - 3) {
return arr.splice(-6, 5);
}
return arr.splice(this.value - 3, 5);
}
public navLeft() {
if (this.value !== 1) {
this.changePage(this.value - 1)
}
}
public navRight() {
if (this.value !== this.pageCount) {
this.changePage(this.value + 1)
}
}
public changePage(val: number) {
if (this.value === val) {
return;
}
this.$emit('input', val);
this.$emit('change', val);
}
}
</script>
<style scoped>
.pagination {
line-height: 20px;
height: 20px;
font-size: 0;
}
.item_box {
vertical-align: top;
display: inline-block;
min-width: 20px;
color: #BABABA;
font-size: 15px;
margin: 0 2px;
text-align: center;
cursor: pointer;
}
.js-item_box_active {
color: #000;
}
.btn_nav {
display: inline-block;
margin: 0 8px 0 0; /* 15 - (20 - 9)/2 - 2*/
width: 20px;
height: 20px;
border-radius: 50%;
line-height: 20px;
text-align: center;
color: #7A7A7A;
background: #F1F1F1;
cursor: pointer;
}
.js-btn_nav_disable {
cursor: not-allowed;
}
.btn_nav-icon {
display: inline-block;
font-size: 14px;
font-weight: 500;
transform: scale(.5);
}
.btn_nav_right {
margin: 0 0 0 8px;
}
.btn_nav-icon_right {
transform: scale(.5) rotate(180deg);
}
</style>
<template>
<div class="bootPage">
<div class="view-windows">
<div class="view-window" :style="Style">
<div class="imgbox url1"></div>
<div class="imgbox url2"></div>
<div class="imgbox url3"></div>
</div>
</div>
<!-- url3 -->
<ul class="list">
<li :class="{'check':index===1}"></li>
<li :class="{'check':index===2}"></li>
<li :class="{'check':index===3}"></li>
</ul>
<div class="content" v-if="index===1">
<h1>存证溯源</h1>
<p>把信息储存到区块链浏览器里,追溯根源安全可靠。</p>
</div>
<div class="content" v-if="index===2">
<h1>增量更新</h1>
<p>多环节操作上链,多次上链,上传便捷。</p>
</div>
<div class="content" v-if="index===3">
<h1>更多功能即将上线</h1>
<p>存证交接成员管理即将上线,敬请期待~</p>
</div>
<div class="btnbox" v-if="index===3">
<div class="btn" @click="determine">确定</div>
</div>
<div class="btnbox" v-else>
<div class="btn" @click="next">下一步</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
index: 1,
containerWidth: 0,
reference: 420
};
},
computed: {
// 图片的左右移动
Style() {
const style = {
transform: "translateX(" + -1 * this.containerWidth + "px)"
};
return style;
}
},
methods: {
determine() {
localStorage.setItem("bootPage", "show2");
this.$emit("close");
},
next() {
let t = setInterval(() => {
this.containerWidth += 10;
if (this.containerWidth == this.reference) {
this.reference = this.reference + 420;
this.index++;
clearInterval(t);
}
}, 1);
}
}
};
</script>
<style lang="less">
* {
margin: 0;
padding: 0;
}
.bootPage {
width: 422px;
height: 490px;
background: rgba(255, 255, 255, 1);
border-radius: 10px;
padding: 26px;
.view-windows {
width: 420px;
overflow: hidden;
height: 195px;
}
.view-window {
width: 1000%;
height: 195px;
}
.imgbox {
width: 420px;
float: left;
height: 195px;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
.url1 {
background-image: url("../../entry/main/images/9@2x.png");
}
.url2 {
background-image: url("../../entry/main/images/13@2x.png");
}
.url3 {
background-image: url("../../entry/main/images/1@2x.png");
}
.list {
list-style: none;
margin: 22px;
overflow: hidden;
margin-left: 194px;
li {
border-radius: 6px;
width: 6px;
cursor: pointer;
background: #b2bcc6;
height: 6px;
float: left;
&:nth-child(2) {
margin-right: 8px;
margin-left: 8px;
}
}
.check {
background: #353535 !important;
}
}
.content {
h1 {
font-size: 22px;
text-align: center;
font-weight: 400;
color: rgba(53, 53, 53, 1);
line-height: 1;
}
p {
text-align: center;
font-size: 16px;
line-height: 1;
font-weight: 400;
padding-top: 20px;
color: rgba(53, 53, 53, 1);
}
}
.btnbox {
margin-top: 126px;
.btn {
margin: 0 auto;
width: 120px;
height: 40px;
cursor: pointer;
text-align: center;
line-height: 40px;
color: white;
background: rgba(63, 121, 254, 1);
border-radius: 4px;
}
}
}
</style>
\ No newline at end of file
...@@ -18,6 +18,17 @@ let router = new Router({ // todo 移除旧页面 ...@@ -18,6 +18,17 @@ let router = new Router({ // todo 移除旧页面
name: 'signIn', name: 'signIn',
component: () => import('./views/SignIn.vue'), component: () => import('./views/SignIn.vue'),
}, },
{
path: '/main',
component: () => import(/* webpackChunkName: "main" */ './views/Main.vue'),
children: [
{
path: '/categoryManage',
name: 'categoryManage',
component: () => import(/* webpackChunkName: "categoryManage" */ './views/category/Index.vue'),
},
]
}
// { // {
// path: '/main', // path: '/main',
// component: () => import(/* webpackChunkName: "main" */ './views/Main.vue'), // component: () => import(/* webpackChunkName: "main" */ './views/Main.vue'),
......
<template>
<div class="main">
<!-- 左侧导航 -->
<main-menu class="col_left" />
<div class="col_right">
<main-header />
<div class="main_wrapper" v-if="freshFlag">
<router-view />
</div>
</div>
<!-- <first-add v-if="showFirstAdd" @finish="handleFinishAdd"/> -->
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
// 本地组件
import MainHeader from "./MainHeader.vue";
import MainMenu from "./MainMenu.vue";
// import FirstAdd from "@/views/FirstAdd.vue";
@Component({
components: {
MainMenu,
MainHeader,
// FirstAdd,
},
})
export default class Main extends Vue {
public uid: string = "";
// public showFirstAdd: boolean = true;
public freshFlag: boolean = true;
public created() {
// this.getUid();
}
// public exit() {
// this.$router.push("/");
// }
/**
* 获取登录管理员的uid
*/
// public getUid() {
// this.uid = "10086";
// }
// public handleFinishAdd(isEdit: boolean) {
// this.showFirstAdd = false;
// if (isEdit) {
// this.freshMain();
// }
// }
// private freshMain() {
// this.freshFlag = false;
// this.$nextTick(() => {
// this.freshFlag = true;
// });
// }
}
</script>
<style scoped>
.main {
display: flex;
height: 100%;
}
.col_left {
flex-shrink: 0;
}
.col_right {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.main_wrapper {
flex: 1;
min-height: 0;
overflow-y: scroll;
background: white;
height: 100%;
}
</style>
<template>
<header class="main_header">
<img class="icon_logo" src="../images/logo.png" alt="logo" />
<div class="user_wrapper">
<i class="iconfont iconShapecopy1"></i>
<span class="user-text">UID:{{getid||"10086"}}</span>
<ul class="menu_box">
<li @click="go('quit')">退出</li>
</ul>
<i class="iconxiangyousanjiao iconfont"></i>
</div>
</header>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import * as storage from "@/entry/refactoring/plugins/storage";
// import { getUserInfo } from "../../../views/userCenter/Api.service";
@Component
export default class MainHeader extends Vue {
get getid() {
return JSON.parse(String(sessionStorage.getItem('user'))).id
}
public go(target: string) {
// if (target === "user") this.$router.push("/userCenter");
// else {
// this.$store.commit("clearUserInfos");
// storage.cleanLogin();
sessionStorage.removeItem("user");
this.$router.push("/");
// }
}
// 获取用户基本信息
// async getUserInfos() {
// // const res = await getUserInfo();
// // if (res && res.code === 200200) {
// // this.$store.commit("updateUserInfo", res.data);
// // }
// }
// public mounted() {
// // this.getUserInfos();
// }
}
</script>
<style scoped lang='less'>
// 大盒子
.main_header {
z-index: 1; /* shadow覆盖底部 */
position: relative;
height: 50px;
padding-right: 35px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 2px 40px 0px rgba(65, 70, 76, 0.07);
}
// logo
.icon_logo {
margin-left: 27px;
margin-top: 12px;
height: 23px;
}
.user_wrapper {
margin-top: 12px;
float: right;
height: 100%;
color: #353535;
cursor: pointer;
.iconShapecopy1 {
vertical-align: middle;
margin-right: 6px;
font-size: 20px;
color: #d6d8e1;
}
.iconxiangyousanjiao {
color: #b4b4b4;
transform: rotate(90deg);
display: inline-block;
font-size: 12px;
margin-left: 14px;
}
}
.user_wrapper .menu_box {
display: none;
}
.user_wrapper:hover .menu_box {
display: block;
}
.user-icon {
/* todo ui切块错误 */
margin-right: 6px;
vertical-align: middle;
height: 20px;
}
.user-text {
vertical-align: middle;
color: #b4b4b4;
}
.menu_box {
position: absolute;
top: 100%;
right: 35px;
margin: 0;
padding: 0;
line-height: 41px; /* 非精确ui */
width: 107px; /* 109 - border */
list-style: none;
border: 1px solid #e7e7e7;
text-align: center;
color: #797d84;
background: #fff;
}
.menu_box li {
transition: 0.5s;
cursor: pointer;
background: white;
}
.menu_box li:hover {
background: #f5f5f5;
}
</style>
<template>
<!-- 左侧导航栏 -->
<nav class="main_menu">
<div
class="menu-item menu-item_first"
:class="{'js-menu-item_active':currentRoute===RoutePages.CategoryManage}"
@click="selectPage(RoutePages.CategoryManage)"
>
<div class="menu-item_subject-icon">
<i class="iconfont">&#xe62b;</i>
</div>
<div class="menu-item-label">存证</div>
<div class="menu-item-active_border"></div>
</div>
<div
class="menu-item menu-item_product"
:class="{'js-menu-item_active':currentRoute===RoutePages.ProductManage}"
@click="goworldtradebase"
>
<div class="menu-item_product-icon">
<i class="iconfont">&#xe629;</i>
</div>
<div class="menu-item-label">溯源</div>
<div class="menu-item-active_border"></div>
</div>
<div class="menu-item menu-item_template" @click="newPage()">
<div class="menu-item_template-icon">
<i class="iconfont">&#xe62a;</i>
</div>
<div class="menu-item-label">管理</div>
<div class="menu-item-active_border"></div>
</div>
</nav>
</template>
<script>
let UrlPrefixObj = require("@/config/UrlPrefix");
export default {
data() {},
methods: {},
};
// import { Component, Prop, Vue } from "vue-property-decorator";
// import { RoutePages } from "@/types/common";
// @Component
// export default class MainMenu extends Vue {
// public RoutePages = RoutePages;
// 选中效果
// data(){
// return{
// }
// },
// currentRoute() {
// return this.$route.matched[1].name;
// }
// 打开区块链浏览器
// goworldtradebase() {
// window.open(UrlPrefixObj.model.CHAIN_BROWSER_URL_PREFIX);
// }
// 跳转页面
// selectPage(page) {
// // this.$router.push(page);
// }
// newPage() {
// this.$router.push("/userCenter");
// }
// }
</script>
<style scoped lang="less">
.main_menu {
width: 62px;
height: 100%;
background: #27272a;
color: rgba(255, 255, 255, 0.6);
text-align: center;
font-size: 12px;
}
.menu-item {
height: 60px;
position: relative;
}
.menu-item_first {
margin-top: 79px;
}
.menu-item_product {
margin-top: 21px; /* 30 - 9 */
}
.menu-item_template {
margin-top: 26px; /* 36 - 10 */
}
.js-menu-item_active {
background: #39393e;
cursor: pointer;
& > .menu-item-active_border {
display: initial;
}
}
.menu-item-active_border {
display: none;
position: absolute;
top: 0;
left: 0;
width: 3px;
height: 100%;
background: #3f79fe;
}
.menu-item_subject-icon {
padding: 14px 0 5px 0;
& > i {
font-size: 14px;
}
}
.menu-item_product-icon {
padding: 12px 0 6px 0;
cursor: pointer;
& > i {
font-size: 15px;
}
}
.menu-item_template-icon {
padding: 9px 0 8px 0;
cursor: pointer;
& > i {
font-size: 16px;
}
}
.menu-item-label {
line-height: 17px;
}
</style>
...@@ -11,3 +11,9 @@ declare global { ...@@ -11,3 +11,9 @@ declare global {
} }
} }
} }
declare global {
interface Window {
callback_sendcode(res: any): void
callback_sendcode2(res: any): void
}
}
\ No newline at end of file
import QRCode from 'qrcode';
import { Notification } from 'element-ui';
import { CHAIN_BROWSER_URL } from "@/config/URLS";
function getChainBrowserUrl(hash: string): string {
return `${CHAIN_BROWSER_URL}${hash}`;
}
/**
* 打开区块链浏览器查询商品
* @param hash
*/
export function openChainBrowser(hash: string) {
window.open(getChainBrowserUrl(hash));
}
// 返回支付二维码
export async function payQR(pay_url: string) {
const res = await QRCode.toDataURL(pay_url)
if (res) {
return res
}
}
// 返回二维码
export async function getQR(hash: string) {
const res = await QRCode.toDataURL(getChainBrowserUrl(hash))
if (res) {
return res
}
}
// 下载二维码
export async function downloadQrCode(hash: string) {
QRCode.toDataURL(getChainBrowserUrl(hash))
.then(url => {
const a = document.createElement('a');
a.download = `二维码${Date.now()}`;
a.href = url;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
})
.catch(() => {
Notification.error('生成二维码失败');
});
}
import _Vue from 'vue'
/**
* 全局filter
*/
/**
* 手机号掩码处理
* @param str
*/
export let filterPhone = (str: string) => String(str).substr(0, 3) + '****' + String(str).substr(-4);
/**
* 时间戳转换
* @param timestamp 时间戳
* @param 转换格式 默认yy-mm-dd hh:mm:ss
*/
export let formatTime = (timestamp: any, format: string = 'Y-M-D h:m:s') => {
if (timestamp == null || timestamp == undefined || timestamp == 0) {
return ''
}
let date = new Date(parseInt(timestamp, 10) * 1000)
let fmtList = [{ k: 'Y', v: "date.getFullYear()" },
{ k: 'M', v: "date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1" },
{ k: 'D', v: "date.getDate() < 10 ? '0' + date.getDate() : date.getDate()" },
{ k: 'h', v: "date.getHours() < 10 ? '0' + date.getHours() : date.getHours()" },
{ k: 'm', v: "date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()" },
{ k: 's', v: "date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()" },
]
for (let i = 0; i < fmtList.length; i++) {
let fmt = fmtList[i];
let k = fmt.k;
if (format.indexOf(k) != -1) {
format = format.replace(k, eval(fmt.v));
}
}
return format;
}
const globalFilters = (Vue: typeof _Vue) => {
Vue.filter('filterPhone', filterPhone)
Vue.filter('formatTime', formatTime)
}
export default globalFilters
\ No newline at end of file
/**
* 工具
*/
/**
* 将图片文件转为DataUrl展示
* @param file
*/
export function file2DataUrl(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e: any) => {
resolve(e.target.result);
};
reader.onerror = () => {
reject('err');
};
});
}
export function fmtTimeStamp(format: string, timestamp: number) {//时间戳转化
if (timestamp == null || timestamp == undefined || timestamp == 0) {
return ''
}
var date = null;
if(String(timestamp).length > 10){
date = new Date(timestamp);
}
else{
date = new Date(timestamp * 1000);
}
var fmtList = [{ k: 'Y', v: "date.getFullYear()" },
{ k: 'M', v: "date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1" },
{ k: 'D', v: "date.getDate() < 10 ? '0' + date.getDate() : date.getDate()" },
{ k: 'h', v: "date.getHours() < 10 ? '0' + date.getHours() : date.getHours()" },
{ k: 'm', v: "date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()" },
{ k: 's', v: "date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()" },
]
for (var i = 0; i < fmtList.length; i++) {
let fmt = fmtList[i];
let k = fmt.k;
if (format.indexOf(k) != -1) {
format = format.replace(k, eval(fmt.v));
}
}
return format;
}
/**
* 获取一个本地用的随机id
*/
export function getUuid() {
return `${Date.now()}${Math.random()}`;
}
import Vue from 'vue';
// import {GetParam, PostParam} from "@/plugins/axios-plugin";
export interface ResBase {
code: number;
data: any;
message: string;
}
// import {ResBase} from "@/types/api";
declare module 'vue/types/vue' {
interface Vue {
$ajax: (param: any) => Promise<ResBase | null>
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment