提交一波轮子
This commit is contained in:
@@ -6,7 +6,7 @@ const start = () => {
|
||||
easycom: {
|
||||
autoscan: true,
|
||||
custom: {
|
||||
"^(K|V)(.*)": "@/components/$1$2.vue",
|
||||
"^(Ai|V)(.*)": "@/components/$1$2.vue",
|
||||
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
"@dcloudio/uni-mp-weixin": "3.0.0-3061420221215001",
|
||||
"@dcloudio/uni-quickapp-webview": "3.0.0-3061420221215001",
|
||||
"@dcloudio/uni-ui": "^1.4.23",
|
||||
"axios": "^1.2.2",
|
||||
"axios-miniprogram-adapter": "^0.3.5",
|
||||
"dayjs": "^1.11.7",
|
||||
"query-string": "^8.1.0",
|
||||
"vue": "^3.2.45",
|
||||
"vue-i18n": "^9.1.9"
|
||||
},
|
||||
|
||||
61
wxmp/src/components/AiGroup.vue
Normal file
61
wxmp/src/components/AiGroup.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<section class="AiGroup" :class="{noBorder,description}" :style="{paddingLeft:left+'rpx'}">
|
||||
<div class="groupHeader" v-if="title" v-text="title"/>
|
||||
<slot/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiGroup",
|
||||
provide() {
|
||||
return {
|
||||
labelColor: this.labelColor,
|
||||
description: this.description,
|
||||
activeStep: this.activeStep
|
||||
}
|
||||
},
|
||||
props: {
|
||||
title: String,
|
||||
noBorder: Boolean,
|
||||
left: {default: 32},
|
||||
labelColor: {default: "#333"},
|
||||
description: {default: false}, //用于展示则不会又红星,会把标签的内间距去掉
|
||||
activeStep: {default: 1}//用于步骤组件的当前步数
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiGroup {
|
||||
background: #FFFFFF;
|
||||
box-shadow: inset 0px -1px 0px 0px #DDDDDD;
|
||||
|
||||
&.noBorder {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
& + .AiGroup {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.groupHeader {
|
||||
font-weight: bold;
|
||||
font-size: 36px;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&.description {
|
||||
.groupHeader {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
124
wxmp/src/components/AiItem.vue
Normal file
124
wxmp/src/components/AiItem.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<section class="AiItem" :class="{border,readonly}">
|
||||
<div v-if="topLabel" class="topLabel">
|
||||
<div class="labelPane flex">
|
||||
<div class="label" :class="{required,labelBold}" :style="{color}" v-text="label"/>
|
||||
<slot name="sub" v-if="$slots.sub"/>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<slot v-if="$slots.default"/>
|
||||
<div v-else v-text="value"/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="normal flex">
|
||||
<div class="fill flex">
|
||||
<div class="label" :class="{required,labelBold}" :style="{color}" v-text="label"/>
|
||||
<slot name="sub" v-if="$slots.sub"/>
|
||||
</div>
|
||||
<div class="flexContent">
|
||||
<slot v-if="$slots.default"/>
|
||||
<div v-else v-text="value"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiItem",
|
||||
inject: {
|
||||
labelColor: {default: "#333"},
|
||||
description: {default: false}
|
||||
},
|
||||
props: {
|
||||
value: {default: ""},
|
||||
label: {default: ""},
|
||||
required: Boolean,
|
||||
topLabel: Boolean,
|
||||
border: {default: true},
|
||||
labelBold: Boolean,
|
||||
},
|
||||
computed: {
|
||||
color: v => v.labelColor,
|
||||
readonly: v => !!v.description
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiItem {
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
|
||||
&.border {
|
||||
.normal {
|
||||
border-bottom: 2px solid #ddd;
|
||||
}
|
||||
|
||||
.topLabel {
|
||||
border-bottom: 2px solid #ddd;
|
||||
}
|
||||
}
|
||||
|
||||
.normal {
|
||||
width: 100%;
|
||||
padding-right: 32px;
|
||||
box-sizing: border-box;
|
||||
height: 112px;
|
||||
|
||||
.flexContent {
|
||||
max-width: 62vw;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
padding-left: 20px;
|
||||
font-weight: 400;
|
||||
margin-right: 20px;
|
||||
position: relative;
|
||||
|
||||
&.required:before {
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
content: "*";
|
||||
color: #f46;
|
||||
}
|
||||
|
||||
&.labelBold {
|
||||
font-weight: bold;
|
||||
font-size: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.topLabel {
|
||||
padding: 32px 32px 32px 0;
|
||||
|
||||
.labelPane {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.itemContent {
|
||||
padding-left: 20px;
|
||||
|
||||
.AiMore > .u-icon {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//展示模式下的特有样式
|
||||
&.readonly {
|
||||
.label, .itemContent {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.AiStep:last-of-type {
|
||||
.stepLine {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
74
wxmp/src/components/AiPagePicker.vue
Normal file
74
wxmp/src/components/AiPagePicker.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<section class="AiPagePicker">
|
||||
<div @click="handleJump">
|
||||
<slot v-if="$slots.default"/>
|
||||
<div v-else v-text="selectedLabel"/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import qs from 'query-string'
|
||||
|
||||
export default {
|
||||
name: "AiPagePicker",
|
||||
model: {
|
||||
prop: "value",
|
||||
event: "input"
|
||||
},
|
||||
props: {
|
||||
value: {default: ""},
|
||||
type: {default: "sysUser"},
|
||||
nodeKey: {default: "id"},
|
||||
selected: {default: () => []},
|
||||
placeholder: {default: "请选择"},
|
||||
ops: {default: () => ({})},
|
||||
valueObj: Boolean,
|
||||
params: {default: () => ({})},
|
||||
multiple: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
configList: {
|
||||
sysUser: {url: "/components/pages/selectSysUser", label: "name"},
|
||||
custom: {...this.ops}
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
config() {
|
||||
return this.configList[this.type] || {}
|
||||
},
|
||||
selectedLabel() {
|
||||
let {placeholder, config: {label}} = this
|
||||
return this.selected?.map(e => e[label])?.toString() || placeholder
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleJump() {
|
||||
let {config, nodeKey, valueObj, multiple} = this,
|
||||
selected = (valueObj ? this.value[nodeKey] : this.value) || this.selected?.map(e => e[nodeKey])
|
||||
uni.$once('pagePicker:' + this.type, data => {
|
||||
console.log('发送', data)
|
||||
this.$emit("update:selected", data)
|
||||
this.$emit("select", data)
|
||||
this.$emit("input", valueObj ? data :
|
||||
data ? (multiple ? [data].flat()?.map(e => e[nodeKey]) : data[nodeKey]) : "")
|
||||
})
|
||||
let url = `${config.url}`,
|
||||
qsstr = qs.stringify({
|
||||
selected, nodeKey, multiple, ...this.params
|
||||
})
|
||||
if (!!qsstr) {
|
||||
url += `?${qsstr}`
|
||||
}
|
||||
uni.navigateTo({url})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiPagePicker {
|
||||
}
|
||||
</style>
|
||||
62
wxmp/src/components/pages/submitEvaluation.vue
Normal file
62
wxmp/src/components/pages/submitEvaluation.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<section class="submitEvaluation">
|
||||
<AiGroup>
|
||||
<AiItem label="评价分数" top-label required>
|
||||
<uni-rate v-model="form.score" :size="64" active-color="#F8B425" :min-count="1" inactive-icon="star-fill"/>
|
||||
</AiItem>
|
||||
</AiGroup>
|
||||
<u-gap height="24"/>
|
||||
<AiGroup>
|
||||
<AiItem label="评价详情" top-label required>
|
||||
<uni-easyinput type="textarea" v-model="form.content" placeholder="请简要描述..."/>
|
||||
</AiItem>
|
||||
</AiGroup>
|
||||
<u-gap height="24"/>
|
||||
<AiGroup>
|
||||
<AiItem label="附件" top-label>
|
||||
<uni-file-picker file-mediatype="all" v-model="form.files" :limit="9" mode="grid"/>
|
||||
</AiItem>
|
||||
</AiGroup>
|
||||
<div class="fixed-bottom">
|
||||
<div class="bottomBtn" @click="submit">提交</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "submitEvaluation",
|
||||
appName: "提交评价",
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
files: []
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
if (!this.form.score) {
|
||||
return this.$toast("请选择评价分数!")
|
||||
}
|
||||
if (!this.form.content) {
|
||||
return this.$toast("请填写评价详情!")
|
||||
}
|
||||
this.$instance.post("/app/appbusinesscompletionevaluation/addOrUpdate", this.form).then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.$toast("提交成功!")
|
||||
setTimeout(() => uni.navigateBack({}), 1500)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onLoad(params) {
|
||||
this.form.bizId = params.bid
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.submitEvaluation {
|
||||
}
|
||||
</style>
|
||||
@@ -1,8 +1,10 @@
|
||||
import {createSSRApp} from "vue";
|
||||
import App from "./App.vue";
|
||||
import util from "./utils/util";
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
Object.keys(util).map(e => app.config.globalProperties[e] = util[e])
|
||||
return {
|
||||
app,
|
||||
};
|
||||
|
||||
19
wxmp/src/utils/coin.js
Normal file
19
wxmp/src/utils/coin.js
Normal file
@@ -0,0 +1,19 @@
|
||||
export default {
|
||||
cny(money) {
|
||||
if (money) {
|
||||
money.toLocaleString('zh-Hans-CN', {style: 'currency', currency: "CNY"})
|
||||
}
|
||||
return money
|
||||
},
|
||||
cn(money) {
|
||||
let num = parseFloat(money), cnMoney = '',
|
||||
units = '仟佰拾亿仟佰拾万仟佰拾元角分',
|
||||
cnNum = '零壹贰叁肆伍陆柒捌玖'
|
||||
num = num.toFixed(2).replace(/\./g, '')
|
||||
units = units.substring(units.length - num.length)
|
||||
Array.from(num).map((e, i) => {
|
||||
cnMoney += cnNum.charAt(e) + units.charAt(i)
|
||||
})
|
||||
return cnMoney.replace(/零角零分$/, '整').replace(/零[仟佰拾]/g, '零').replace(/零{2,}/g, '零').replace(/零([亿|万])/g, '$1').replace(/零+元/, '元').replace(/亿零{0,3}万/, '亿').replace(/^元/, "零元")
|
||||
}
|
||||
}
|
||||
56
wxmp/src/utils/dict.js
Normal file
56
wxmp/src/utils/dict.js
Normal file
@@ -0,0 +1,56 @@
|
||||
export default {
|
||||
instance: null,
|
||||
init(instance) {
|
||||
this.instance = instance
|
||||
},
|
||||
dicts() {
|
||||
return uni.getStorageSync('dicts') || [];
|
||||
},
|
||||
load(...code) {
|
||||
return !!this.instance && this.instance.post('/admin/dictionary/queryValsByCodeList?codeList=' + code.join(','), null, {
|
||||
withoutToken: true
|
||||
}).then((res) => {
|
||||
if (res && res.data) {
|
||||
let cacheDicts = {},
|
||||
meta = {};
|
||||
this.dicts().map((e) => (cacheDicts[e.key] = e));
|
||||
res.data.map((e) => (meta[e.key] = e));
|
||||
let dicts = {...cacheDicts, ...meta};
|
||||
uni.setStorageSync('dicts', Object.values(dicts));
|
||||
}
|
||||
});
|
||||
},
|
||||
getDict(key) {
|
||||
if (this.dicts().length) {
|
||||
let dict = this.dicts().find((e) => e.key == key);
|
||||
return dict ? dict.values : [];
|
||||
} else return [];
|
||||
},
|
||||
getValue(key, label) {
|
||||
if (this.dicts().length) {
|
||||
let dict = this.dicts().find((e) => e.key == key);
|
||||
if (dict) {
|
||||
let item = dict.values.find((v) => v.dictName == label);
|
||||
return item ? item.dictValue : label;
|
||||
} else return label;
|
||||
} else return label;
|
||||
},
|
||||
getLabel(key, value) {
|
||||
if (this.dicts().length) {
|
||||
let dict = this.dicts().find((e) => e.key == key);
|
||||
if (dict) {
|
||||
let item = dict.values.find((v) => v.dictValue == value);
|
||||
return item ? item.dictName : value;
|
||||
} else return value ? value : '';
|
||||
} else return value ? value : '';
|
||||
},
|
||||
getColor(key, value) {
|
||||
if (this.dicts().length) {
|
||||
let dict = this.dicts().find((e) => e.key == key);
|
||||
if (dict) {
|
||||
let item = dict.values.find((v) => v.dictValue == value);
|
||||
return item ? item.dictColor : value;
|
||||
} else return value;
|
||||
} else return value;
|
||||
}
|
||||
}
|
||||
29
wxmp/src/utils/http.js
Normal file
29
wxmp/src/utils/http.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios'
|
||||
import adapter from 'axios-miniprogram-adapter'
|
||||
|
||||
const instance = axios.create({
|
||||
timeout: 600000,
|
||||
withCredentials: true,
|
||||
adapter
|
||||
})
|
||||
const getToken = () => {
|
||||
let vuex = uni.getStorageSync("vuex")
|
||||
return !!vuex ? JSON.parse(vuex).token : null
|
||||
}
|
||||
const source = axios.CancelToken.source();
|
||||
instance.interceptors.request.use(config => {
|
||||
if (config.withoutToken) {
|
||||
return config
|
||||
} else if (getToken()) {
|
||||
config.headers["Authorization"] = getToken()
|
||||
} else {
|
||||
config.cancelToken = source.token
|
||||
source.cancel("用户未验证,取消请求:" + config.url)
|
||||
}
|
||||
return config
|
||||
}, err => {
|
||||
console.error(err)
|
||||
return Promise.reject(err)
|
||||
})
|
||||
|
||||
export default instance
|
||||
238
wxmp/src/utils/identity.js
Normal file
238
wxmp/src/utils/identity.js
Normal file
@@ -0,0 +1,238 @@
|
||||
import dayjs from "./moment";
|
||||
|
||||
|
||||
const PARAMS = {
|
||||
/* 省,直辖市代码表 */
|
||||
provinceAndCitys: {
|
||||
11: '北京',
|
||||
12: '天津',
|
||||
13: '河北',
|
||||
14: '山西',
|
||||
15: '内蒙古',
|
||||
21: '辽宁',
|
||||
22: '吉林',
|
||||
23: '黑龙江',
|
||||
31: '上海',
|
||||
32: '江苏',
|
||||
33: '浙江',
|
||||
34: '安徽',
|
||||
35: '福建',
|
||||
36: '江西',
|
||||
37: '山东',
|
||||
41: '河南',
|
||||
42: '湖北',
|
||||
43: '湖南',
|
||||
44: '广东',
|
||||
45: '广西',
|
||||
46: '海南',
|
||||
50: '重庆',
|
||||
51: '四川',
|
||||
52: '贵州',
|
||||
53: '云南',
|
||||
54: '西藏',
|
||||
61: '陕西',
|
||||
62: '甘肃',
|
||||
63: '青海',
|
||||
64: '宁夏',
|
||||
65: '新疆',
|
||||
71: '台湾',
|
||||
81: '香港',
|
||||
82: '澳门',
|
||||
91: '国外'
|
||||
},
|
||||
|
||||
/* 每位加权因子 */
|
||||
powers: [
|
||||
'7',
|
||||
'9',
|
||||
'10',
|
||||
'5',
|
||||
'8',
|
||||
'4',
|
||||
'2',
|
||||
'1',
|
||||
'6',
|
||||
'3',
|
||||
'7',
|
||||
'9',
|
||||
'10',
|
||||
'5',
|
||||
'8',
|
||||
'4',
|
||||
'2'
|
||||
],
|
||||
|
||||
/* 第18位校检码 */
|
||||
parityBit: ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'],
|
||||
|
||||
/* 性别 */
|
||||
genders: {1: '男', 0: '女'},
|
||||
}
|
||||
|
||||
const Check = {
|
||||
/* 校验地址码 */
|
||||
checkAddressCode(addressCode) {
|
||||
const check = /^[1-9]\d{5}$/.test(addressCode)
|
||||
if (!check) return false
|
||||
return !!PARAMS.provinceAndCitys[parseInt(addressCode.substring(0, 2))]
|
||||
},
|
||||
/* 校验日期码 */
|
||||
checkBirthDayCode(birDayCode) {
|
||||
const check = /^[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))$/.test(
|
||||
birDayCode
|
||||
)
|
||||
if (!check) return false
|
||||
const yyyy = parseInt(birDayCode.substring(0, 4), 10)
|
||||
const mm = parseInt(birDayCode.substring(4, 6), 10)
|
||||
const dd = parseInt(birDayCode.substring(6), 10)
|
||||
const xdata = new Date(yyyy, mm - 1, dd)
|
||||
if (xdata > new Date()) {
|
||||
return false // 生日不能大于当前日期
|
||||
} else {
|
||||
return (
|
||||
xdata.getFullYear() == yyyy &&
|
||||
xdata.getMonth() == mm - 1 &&
|
||||
xdata.getDate() == dd
|
||||
)
|
||||
}
|
||||
},
|
||||
/* 验证校检码 */
|
||||
checkParityBit(idCardNo) {
|
||||
const parityBit = idCardNo.charAt(17).toUpperCase()
|
||||
return this.getParityBit(idCardNo) == parityBit
|
||||
},
|
||||
// 校验15位的身份证号码
|
||||
check15IdCardNo(idCardNo) {
|
||||
// 15位身份证号码的基本校验
|
||||
let check = /^[1-9]\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}$/.test(
|
||||
idCardNo
|
||||
)
|
||||
if (!check) return false
|
||||
// 校验地址码
|
||||
const addressCode = idCardNo.substring(0, 6)
|
||||
check = this.checkAddressCode(addressCode)
|
||||
if (!check) return false
|
||||
const birDayCode = '19' + idCardNo.substring(6, 12)
|
||||
// 校验日期码
|
||||
return this.checkBirthDayCode(birDayCode)
|
||||
},
|
||||
|
||||
// 校验18位的身份证号码
|
||||
check18IdCardNo(idCardNo) {
|
||||
// 18位身份证号码的基本格式校验
|
||||
let check = /^[1-9]\d{5}[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}(\d|x|X)$/.test(
|
||||
idCardNo
|
||||
)
|
||||
if (!check) return false
|
||||
// 校验地址码
|
||||
const addressCode = idCardNo.substring(0, 6)
|
||||
check = this.checkAddressCode(addressCode)
|
||||
if (!check) return false
|
||||
// 校验日期码
|
||||
const birDayCode = idCardNo.substring(6, 14)
|
||||
check = this.checkBirthDayCode(birDayCode)
|
||||
if (!check) return false
|
||||
// 验证校检码
|
||||
return this.checkParityBit(idCardNo)
|
||||
},
|
||||
/* 计算校检码 */
|
||||
getParityBit(idCardNo) {
|
||||
const id17 = idCardNo.substring(0, 17)
|
||||
/* 加权 */
|
||||
let power = 0
|
||||
for (let i = 0; i < 17; i++) {
|
||||
power += parseInt(id17.charAt(i), 10) * parseInt(PARAMS.powers[i])
|
||||
}
|
||||
/* 取模 */
|
||||
const mod = power % 11
|
||||
return PARAMS.parityBit[mod]
|
||||
}
|
||||
}
|
||||
|
||||
export default class Identity {
|
||||
constructor(code) {
|
||||
this.code = this.getId18(code)
|
||||
this.init()
|
||||
}
|
||||
|
||||
init() {
|
||||
const {code} = this
|
||||
if (!!code) {
|
||||
this.hideCode = Identity.hideId(code)
|
||||
this.getIdCardInfo(code)
|
||||
}
|
||||
}
|
||||
|
||||
static hideId(code) {
|
||||
return code?.replace(/^(\d{10})\d{4}(.{4}$)/g, `$1${Array(5).join('*')}$2`)
|
||||
}
|
||||
|
||||
getId18(code) {
|
||||
if (code.length == 15) {
|
||||
const id17 = code.substring(0, 6) + '19' + code.substring(6)
|
||||
const parityBit = Check.getParityBit(id17)
|
||||
return id17 + parityBit
|
||||
} else if (code.length == 18) {
|
||||
return code
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
getIdCardInfo(idCardNo) {
|
||||
this.birthday = Identity.getBirthday(idCardNo)
|
||||
this.sex = Identity.getSex(idCardNo)
|
||||
this.gender = PARAMS.genders[this.sex]
|
||||
this.age = Identity.getAge(idCardNo)
|
||||
this.areaId = Identity.getArea(idCardNo)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取性别
|
||||
* @param code
|
||||
* @returns {string}
|
||||
*/
|
||||
static getSex(code) {
|
||||
return (Number(code.substring(16, 17)) % 2).toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取年龄
|
||||
* @param code
|
||||
* @returns {number}
|
||||
*/
|
||||
static getAge(code) {
|
||||
const birthday = dayjs(code.substring(6, 14), 'YYYYMMDD')
|
||||
return Math.ceil(dayjs.duration(dayjs().unix() - dayjs(birthday).unix(), 's').asYears())
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区编码
|
||||
* @param code
|
||||
*/
|
||||
static getArea(code) {
|
||||
return code.substring(0, 6) + new Array(7).join(0)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取生日
|
||||
*/
|
||||
static getBirthday(code) {
|
||||
return dayjs(code.substring(6, 14), 'YYYYMMDD').format("YYYY-MM-DD").replace('Invalid Date', '')
|
||||
}
|
||||
|
||||
/* 校验15位或18位的身份证号码 */
|
||||
static check(idCardNo) {
|
||||
// 15位和18位身份证号码的基本校验
|
||||
const check = /^\d{15}|(\d{17}(\d|x|X))$/.test(idCardNo)
|
||||
if (!check) return false
|
||||
// 判断长度为15位或18位
|
||||
if (idCardNo.length == 15) {
|
||||
return Check.check15IdCardNo(idCardNo)
|
||||
} else if (idCardNo.length == 18) {
|
||||
return Check.check18IdCardNo(idCardNo)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
35
wxmp/src/utils/moment.js
Normal file
35
wxmp/src/utils/moment.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import moment from 'dayjs'
|
||||
import duration from 'dayjs/plugin/duration'
|
||||
import updateLocale from 'dayjs/plugin/updateLocale'
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
|
||||
moment.locale('zh-cn')
|
||||
moment.extend(updateLocale)
|
||||
moment.extend(customParseFormat)
|
||||
moment.extend(duration)
|
||||
moment.updateLocale('zh-cn', {
|
||||
weekdays: "星期日|星期一|星期二|星期三|星期四|星期五|星期六".split("|"),
|
||||
meridiem(hour) {
|
||||
let word = ""
|
||||
if (hour < 6) {
|
||||
word = "凌晨"
|
||||
} else if (hour < 9) {
|
||||
word = "早上"
|
||||
} else if (hour < 12) {
|
||||
word = "上午"
|
||||
} else if (hour < 14) {
|
||||
word = "中午"
|
||||
} else if (hour < 17) {
|
||||
word = "下午"
|
||||
} else if (hour < 19) {
|
||||
word = "傍晚"
|
||||
} else if (hour < 22) {
|
||||
word = "晚上"
|
||||
} else {
|
||||
word = "夜里"
|
||||
}
|
||||
return word;
|
||||
}
|
||||
})
|
||||
export default moment
|
||||
15
wxmp/src/utils/regular.js
Normal file
15
wxmp/src/utils/regular.js
Normal file
@@ -0,0 +1,15 @@
|
||||
export default {
|
||||
phone: /^((0\d{2,3}-\d{7,8})|((13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}))$/,
|
||||
password: /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[~!@#$%^&*,.?_-])[\da-zA-Z~!@#$%^&*,.?_-]{8,16}$/,
|
||||
money: /^([1-9]\d*|0)(\.\d{1,2})?$/,
|
||||
area: {
|
||||
village: /^\d{9}[^0]0{0,2}$/,
|
||||
town: /^\d{6}[^0]0{0,2}000$/,
|
||||
country: /^\d{4}[^0]0?0{6}$/,
|
||||
city: /^\d{2}[^0]0?0{8}$/,
|
||||
province: /^[^0]0?0{10}$/,
|
||||
},
|
||||
zh: /^[\u4e00-\u9fa5]+$/,
|
||||
email: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
|
||||
ip: /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/
|
||||
}
|
||||
140
wxmp/src/utils/util.js
Normal file
140
wxmp/src/utils/util.js
Normal file
@@ -0,0 +1,140 @@
|
||||
import $dayjs from './moment'
|
||||
import $dict from './dict'
|
||||
import $qs from 'query-string'
|
||||
import $coin from './coin'
|
||||
import $reg from "./regular"
|
||||
import identity from "./identity"
|
||||
|
||||
const $toast = (obj) => {
|
||||
let params = {title: '', duration: 2000, icon: 'none'};
|
||||
if (typeof obj == 'string') {
|
||||
params.title = obj;
|
||||
} else {
|
||||
Object.assign(params, obj);
|
||||
}
|
||||
uni.showToast(params);
|
||||
};
|
||||
|
||||
const $loading = (title = "加载中") => {
|
||||
uni.showLoading({
|
||||
title: title || '加载中',
|
||||
mask: true
|
||||
});
|
||||
};
|
||||
|
||||
const $hideLoading = () => {
|
||||
uni.hideLoading();
|
||||
};
|
||||
|
||||
const $dialog = {
|
||||
alert: (params) => {
|
||||
return new Promise((resolve) => {
|
||||
uni.showModal({
|
||||
title: '温馨提示',
|
||||
showCancel: false,
|
||||
confirmColor: '#197DF0',
|
||||
confirmText: params?.confirmButtonText || '确定',
|
||||
...params,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
confirm: (params) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.showModal({
|
||||
title: '温馨提示',
|
||||
showCancel: true,
|
||||
confirmColor: '#197DF0',
|
||||
cancelText: params.cancelButtonText ? params.cancelButtonText : '取消',
|
||||
confirmText: params.confirmButtonText ? params.confirmButtonText : '确定',
|
||||
...params,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
resolve();
|
||||
} else if (res.cancel) {
|
||||
reject();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const $linkTo = (url) => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
});
|
||||
};
|
||||
|
||||
const $formatName = (name) => {
|
||||
if (name === undefined) {
|
||||
return;
|
||||
}
|
||||
return name.substr(name.length - 2, name.length > 2 ? name.length - 1 : name.length);
|
||||
};
|
||||
|
||||
const $previewImage = (list, index, urlName) => {
|
||||
uni.previewImage({
|
||||
current: list[index][urlName],
|
||||
urls: list.map((v) => v[urlName])
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const $getUserProfile = () => {
|
||||
return new Promise(function (resolve) {
|
||||
wx.getUserProfile({
|
||||
desc: '用于完善会员资料',
|
||||
lang: 'zh_CN',
|
||||
success: (data) => {
|
||||
resolve(data);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 获取code
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
const $getLoginCode = () => {
|
||||
return new Promise(function (resolve, reject) {
|
||||
uni.login({
|
||||
success: function (res) {
|
||||
if (res.code) {
|
||||
resolve(res);
|
||||
} else {
|
||||
reject(res);
|
||||
}
|
||||
},
|
||||
fail: function () {
|
||||
reject(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
$toast,
|
||||
$loading,
|
||||
$hideLoading,
|
||||
$dialog,
|
||||
$linkTo,
|
||||
$formatName,
|
||||
$previewImage,
|
||||
$getUserProfile,
|
||||
$dayjs,
|
||||
$dict,
|
||||
$getLoginCode,
|
||||
$qs,
|
||||
$coin,
|
||||
$reg,
|
||||
$ChID: identity
|
||||
};
|
||||
Reference in New Issue
Block a user