Browse Source

Merge branch 'refs/heads/milestone-20250815-金币优化' into lihui/feature-20250815155204-金币优化

zhangyong/feature-20250815160302-金币优化
lihui 2 months ago
parent
commit
7d4bc3cf50
  1. 8
      src/components/changePassword.vue
  2. 185
      src/views/consume/bean/addBeanConsume.vue
  3. 8
      src/views/consume/bean/beanConsume.vue
  4. 7
      src/views/consume/gold/addCoinConsume.vue
  5. 2
      src/views/consume/gold/coinConsumeDetail.vue
  6. 13
      src/views/home.vue
  7. 2
      src/views/login.vue
  8. 197
      src/views/recharge/bean/addBeanRecharge.vue
  9. 296
      src/views/recharge/gold/addCoinRecharge.vue
  10. 360
      src/views/workspace/index.vue

8
src/components/changePassword.vue

@ -32,7 +32,9 @@ const getAccount= async function() {
}
}
//
const isLengthValid = computed(() => passwd.newPassword.length >= 8 && passwd.newPassword.length <= 16)
const isLengthValid = computed(() =>
/^[A-Za-z0-9~!@#$%^&*()_+\-=[\]{}|;:,.<>?/]{8,16}$/.test(passwd.newPassword)
);
const isComplexValid = computed(() => {
const rules = [/\d/, /[a-z]/, /[A-Z]/, /[^a-zA-Z0-9]/]
@ -62,7 +64,7 @@ const rules = reactive({
} else if (value.length < 8 || value.length > 16) {
callback(new Error('长度应在 8 到 16 个字符'))
} else {
const types = [/\d/, /[a-z]/, /[A-Z]/, /[^a-zA-Z0-9]/]
const types = [/\d/, /[a-z]/, /[A-Z]/, /[!@#$%^&*()\-_+={}[\]|\\:;"'<>,.?/~`]/];
const matchCount = types.filter((r) => r.test(value)).length
if (matchCount < 2) {
callback(new Error('密码至少包含两种类型(数字、字母或符号)'))
@ -115,7 +117,7 @@ const changePassword = async function () {
router.push('/PasswordSuccess');
}, 1000);
}else if (result.code === 0){
ElMessage.error('原密码错误')
ElMessage.error('原密码错误,请重新输入')
passwd.oldPassword = '';
}else if(result.code === 400){

185
src/views/consume/bean/addBeanConsume.vue

@ -206,89 +206,120 @@ const throttledHandleConsumeFormt = _.throttle(handleConsumeForm, 5000, {
</script>
<template>
<div>
<el-form :model="consumeForm" :rules="rules" ref="formRef" label-width="auto" style="max-width: 600px"
class="consume-form">
<el-form-item prop="jwcode" label="精网号" label-position="left">
<el-input v-model="consumeForm.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(consumeForm.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<el-form-item prop="permanentBean" label="付费金豆" label-position="left">
<el-input v-model="consumeForm.permanentBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="freeBean" label="免费金豆" label-position="left">
<el-input v-model="consumeForm.freeBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="remark" label="备注" label-position="left">
<el-input v-model="consumeForm.remark" style="width: 300px" :rows="5" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<!-- <el-form-item prop="adminName" label="提交人">
<div class="userAndform">
<div class="left">
<el-form :model="consumeForm" :rules="rules" ref="formRef" label-width="auto" style="max-width: 600px"
class="add-form">
<el-form-item prop="jwcode" label="精网号" label-position="left">
<el-input v-model="consumeForm.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(consumeForm.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<el-form-item prop="permanentBean" label="付费金豆" label-position="left">
<el-input v-model="consumeForm.permanentBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="freeBean" label="免费金豆" label-position="left">
<el-input v-model="consumeForm.freeBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="remark" label="备注" label-position="left">
<el-input v-model="consumeForm.remark" style="width: 300px" :rows="5" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<!-- <el-form-item prop="adminName" label="提交人">
<el-input style="width: 300px" :value="adminData.adminName" disabled placeholder="提交人姓名" />
</el-form-item> -->
<el-button @click="deleteConsumeForm" style="margin-left: 280px" type="success">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="handleConsumeForm"> 提交 </el-button>
</el-form>
<el-button @click="deleteConsumeForm" style="margin-left: 280px" type="success">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="handleConsumeForm"> 提交 </el-button>
</el-form>
</div>
<div class="right">
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" class="customer-info">
<el-form :model="user" label-width="auto" label-position="left">
<el-text size="large" style="min-width: 600px;">客户信息</el-text>
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" class="customer-info">
<el-form :model="user" label-width="auto" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<!-- 第一行姓名 + 当前付费金豆 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名:">
<p style="color: #2fa1ff; margin-right: 5px">{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前付费金豆:">
<p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.permanentBean))">
{{ Number(user.permanentBean) }}
</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
</el-form-item>
</el-col>
</el-row>
<!-- 第一行姓名 + 当前付费金豆 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名:">
<p style="color: #2fa1ff; margin-right: 5px">{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前付费金豆:">
<p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.permanentBean))">
{{ Number(user.permanentBean) }}
</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行精网号 + 免费金豆 -->
<el-row>
<el-col :span="9">
<el-form-item label="精网号">
<p style="color: #2fa1ff; margin-right: 5px">{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前免费金豆:">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.freeBean !== undefined">{{ user.freeBean }}
</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="所属门店">
<p style="color: #2fa1ff">{{ user.market }}</p>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="消耗金豆总数">
<p style="color: #2fa1ff; margin-right: 5px" v-if="user.consumeSum != null">{{ user.consumeSum }}</p>
<p style="color: #2fa1ff; margin-right: 5px" v-else>{{ 0 }}</p>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 第二行精网号 + 免费金豆 -->
<el-row>
<el-col :span="9">
<el-form-item label="精网号">
<p style="color: #2fa1ff; margin-right: 5px">{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前免费金豆:">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.freeBean !== undefined">{{ user.freeBean }}
</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="所属门店">
<p style="color: #2fa1ff">{{ user.market }}</p>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="消耗金豆总数">
<p style="color: #2fa1ff; margin-right: 5px" v-if="user.consumeSum != null">{{ user.consumeSum }}</p>
<p style="color: #2fa1ff; margin-right: 5px" v-else>{{ 0 }}</p>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</div>
</div>
</template>
<style scoped>
.consume-form {
margin-top: 50px;
max-width: 50%;
float: left;
<style scoped lang="scss">
.userAndform {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
.left {
width: 35%;
display: flex;
.add-form {
width: 100%;
margin-top: 50px;
}
}
.right {
flex: 1;
margin-left: 50px;
display: flex;
.beautiful {
width: 90%;
display: flex;
justify-content: center;
align-items: center;
padding: 0 10px;
}
}
}
.customer-info {

8
src/views/consume/bean/beanConsume.vue

@ -34,6 +34,8 @@
文章/视频
</el-button>
</el-button-group>
</div>
<div class="content">
<router-view></router-view>
</div>
</template>
@ -108,3 +110,9 @@ onMounted(() => {
}
});
</script>
<style scoped>
.content{
width: 90%;
height: 90%;
}
</style>

7
src/views/consume/gold/addCoinConsume.vue

@ -787,7 +787,8 @@ onMounted(async function () {
</template>
<style scoped>
<style scoped lang="scss">
p {
margin: 0px;
}
@ -847,9 +848,11 @@ p {
display: flex;
.left {
width: 35%;
width: 500px;
float: left;
align-items: center;
display: flex;
align-items: center;
}
.right {

2
src/views/consume/gold/coinConsumeDetail.vue

@ -564,7 +564,7 @@ const getMarket = async function () {
<el-text class="mx-1" size="large">商品名称</el-text>
<el-select v-model="consumeUser.goodsName" placeholder="请选择商品名称" style="width: 180px" clearable>
<!-- 修改 v-for 绑定逻辑 -->
<el-option v-for="(item, index) in goods" :key="item.id" :label="item.goodsname " :value="item.goodsname" />
<el-option v-for="(item, index) in goods" :key="index" :label="item " :value="item" />
</el-select>
</div>
</el-col>

13
src/views/home.vue

@ -69,12 +69,17 @@ const message = function () {
//
const showPasswordDialog = ref(false)
const pwdRef = ref()
//
const openChangePassword = () => {
showPasswordDialog.value = true
}
//
function onPwdDialogClosed () {
// resetFields
pwdRef.value?.resetFields()
}
function logout() {
const machineId = localStorage.getItem('machineId')
@ -229,8 +234,12 @@ function logout() {
v-model="showPasswordDialog"
:center="true"
width="470px"
@closed="onPwdDialogClosed"
>
<ChangePassword @confirm="showPasswordDialog = false"/>
<ChangePassword
ref="pwdRef"
@confirm="showPasswordDialog = false"
/>
</el-dialog>

2
src/views/login.vue

@ -185,7 +185,7 @@ onMounted(() => {
</el-row>
</template>
<style scoped>
<style scoped lang="scss">
.bg {
border-radius: 0 20px 20px 0;
height: 110vh;

197
src/views/recharge/bean/addBeanRecharge.vue

@ -76,7 +76,7 @@ const rules = reactive({
{ required: true, message: '请输入付费金豆数', trigger: 'change' },
{
validator: (rule, value, callback) => {
if(!value){
if (!value) {
value = 0
}
//
@ -100,7 +100,7 @@ const rules = reactive({
{ required: true, message: '请输入免费金豆数', trigger: 'change' },
{
validator: (rule, value, callback) => {
if(!value){
if (!value) {
value = 0
}
//
@ -131,10 +131,10 @@ const deleteAddForm = function () {
const handleAddForm = async () => {
try {
if(!addForm.value.permanentBean ){
if (!addForm.value.permanentBean) {
addForm.value.permanentBean = 0
}
if(!addForm.value.freeBean ){
if (!addForm.value.freeBean) {
addForm.value.freeBean = 0
}
await new Promise((resolve, reject) => {
@ -175,9 +175,9 @@ const handleAddForm = async () => {
addDisabled.value = false
if (result.code == 200) {
ElMessage.success('新增成功')
deleteAddForm()
deleteAddForm()
user.value = {}
}else{
} else {
ElMessage.error(result.msg)
}
} catch (error) {
@ -188,92 +188,124 @@ const handleAddForm = async () => {
</script>
<template>
<div>
<el-form :model="addForm" :rules="rules" ref="formRef" label-width="auto" style="max-width: 600px" class="add-form">
<el-form-item prop="jwcode" label="精网号" label-position="left">
<el-input v-model="addForm.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(addForm.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<el-form-item prop="permanentBean" label="付费金豆" label-position="left">
<el-input v-model="addForm.permanentBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="freeBean" label="免费金豆" label-position="left">
<el-input v-model="addForm.freeBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="remark" label="备注" label-position="left">
<el-input v-model="addForm.remark" style="width: 300px" :rows="5" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<!-- <el-form-item prop="adminName" label="提交人">
<div class="userAndform">
<div class="left">
<el-form :model="addForm" :rules="rules" ref="formRef" label-width="auto" style="max-width: 600px"
class="add-form">
<el-form-item prop="jwcode" label="精网号" label-position="left">
<el-input v-model="addForm.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(addForm.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<el-form-item prop="permanentBean" label="付费金豆" label-position="left">
<el-input v-model="addForm.permanentBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="freeBean" label="免费金豆" label-position="left">
<el-input v-model="addForm.freeBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="remark" label="备注" label-position="left">
<el-input v-model="addForm.remark" style="width: 300px" :rows="5" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<!-- <el-form-item prop="adminName" label="提交人">
<el-input style="width: 300px" :value="adminData.adminName" disabled placeholder="提交人姓名" />
</el-form-item> -->
<el-button @click="deleteAddForm" style="margin-left: 280px" type="success">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="handleAddForm"> 提交 </el-button>
</el-form>
<el-button @click="deleteAddForm" style="margin-left: 280px" type="success">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="handleAddForm"> 提交 </el-button>
</el-form>
</div>
<div class="right">
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" class="customer-info">
<el-form :model="user" label-width="auto" style="min-width: 600px" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" class="customer-info">
<el-form :model="user" label-width="auto" style="max-width: 1000px" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<!-- 第一行姓名 + 当前付费金豆 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名:">
<p style="color: #2fa1ff; margin-right: 5px">{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前付费金豆:">
<p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.permanentBean))">
{{ Number(user.permanentBean) }}
</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
</el-form-item>
</el-col>
</el-row>
<!-- 第一行姓名 + 当前付费金豆 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名:">
<p style="color: #2fa1ff; margin-right: 5px">{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前付费金豆:">
<p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.permanentBean))">
{{ Number(user.permanentBean) }}
</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行精网号 + 免费金豆 -->
<el-row>
<el-col :span="9">
<el-form-item label="精网号:">
<p style="color: #2fa1ff; margin-right: 5px">{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前免费金豆:">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.freeBean !== undefined">{{ user.freeBean }}
</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="所属门店:">
<p style="color: #2fa1ff">{{ user.market }}</p>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="消耗金豆总数:">
<p style="color: #2fa1ff; margin-right: 5px" v-if="user.consumeSum != null">{{ user.consumeSum }}</p>
<p style="color: #2fa1ff; margin-right: 5px" v-else>{{ 0 }}</p>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</div>
<!-- 第二行精网号 + 免费金豆 -->
<el-row>
<el-col :span="9">
<el-form-item label="精网号:">
<p style="color: #2fa1ff; margin-right: 5px">{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前免费金豆:">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.freeBean !== undefined">{{ user.freeBean }}
</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="所属门店:">
<p style="color: #2fa1ff">{{ user.market }}</p>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="消耗金豆总数:">
<p style="color: #2fa1ff; margin-right: 5px" v-if="user.consumeSum != null">{{ user.consumeSum }}</p>
<p style="color: #2fa1ff; margin-right: 5px" v-else>{{ 0 }}</p>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</template>
<style scoped>
.add-form {
margin-top: 50px;
max-width: 50%;
float: left;
}
.userAndform {
width: 100%;
height: 100%;
display: flex;
align-items: center;
.left {
width: 35%;
display: flex;
align-items: center;
.add-form {
width: 100%;
margin-top: 50px;
}
}
.right {
flex: 1;
margin-left: 50px;
display: flex;
.beautiful {
width: 90%;
display: flex;
justify-content: center;
align-items: center;
padding: 0 10px;
}
}
}
.customer-info {
width: 700px;
float: right;
@ -285,7 +317,4 @@ p {
margin: 0px;
}
.el-form-item {
margin-left: 50px;
}
</style>

296
src/views/recharge/gold/addCoinRecharge.vue

@ -660,133 +660,138 @@ onMounted(() => {
<template>
<div>
<div class="userAndForm">
<el-form :model="recharge" ref="Ref" :rules="rules" label-width="auto" label-position="right"
style="max-width: 600px" class="add-form">
<el-form-item prop="jwcode" label="精网号">
<el-input v-model="recharge.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(recharge.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<el-form-item prop="activity" label="活动名称">
<el-input v-model="recharge.activity" placeholder="请输入活动名称" style="width: 300px" />
</el-form-item>
<el-form-item prop="permanentGold" label="永久金币">
<el-input v-model="recharge.permanentGold" placeholder="0" style="width: 100px" />
<p>&nbsp;</p>
</el-form-item>
<el-form-item prop="freeGold" label="免费金币">
<el-input v-model="recharge.freeGold" placeholder="0" style="width: 100px" />
<p>&nbsp;</p>
</el-form-item>
<el-form-item label="充值金额" required>
<el-form-item prop="rateName" style="display: inline-block; margin-left:0;">
<el-select v-model="recharge.rateName" placeholder="货币名称" style="width: 100px">
<el-option v-for="item in rateName" :key="item.value" :label="item.label" :value="item.value" />
<div class="left">
<el-form :model="recharge" ref="Ref" :rules="rules" label-width="auto" label-position="right"
style="max-width: 600px" class="add-form">
<el-form-item prop="jwcode" label="精网号">
<el-input v-model="recharge.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(recharge.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<el-form-item prop="activity" label="活动名称">
<el-input v-model="recharge.activity" placeholder="请输入活动名称" style="width: 300px" />
</el-form-item>
<el-form-item prop="permanentGold" label="永久金币">
<el-input v-model="recharge.permanentGold" placeholder="0" style="width: 100px" />
<p>&nbsp;</p>
</el-form-item>
<el-form-item prop="freeGold" label="免费金币">
<el-input v-model="recharge.freeGold" placeholder="0" style="width: 100px" />
<p>&nbsp;</p>
</el-form-item>
<el-form-item label="充值金额" required>
<el-form-item prop="rateName" style="display: inline-block; margin-left:0;">
<el-select v-model="recharge.rateName" placeholder="货币名称" style="width: 100px">
<el-option v-for="item in rateName" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item prop="money" style="display: inline-block; margin-left:10px;">
<el-input v-model="recharge.money" style="width: 190px" />
</el-form-item>
</el-form-item>
<el-form-item prop="payModel" label="收款方式">
<el-select v-model="recharge.payModel" placeholder="请选择" style="width: 300px">
<el-option v-for="item in payModel" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item prop="money" style="display: inline-block; margin-left:10px;">
<el-input v-model="recharge.money" style="width: 190px" />
<el-form-item prop="payTime" label="交款时间">
<!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
<el-date-picker v-model="recharge.payTime" type="datetime" style="width: 300px" />
</el-form-item>
<el-form-item prop="voucher" label="交款凭证" style="margin-bottom: 5px">
<el-upload :http-request="customUpload" class="avatar-uploader" :show-file-list="false"
:before-upload="beforeAvatarUpload" style="width: 100px; height: 115px">
<img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 100px; height: 115px" />
<el-icon v-else class="avatar-uploader-icon" style="width: 100px; height: 100px">
<Plus />
</el-icon>
</el-upload>
<p style="margin-left: 10px; color: rgb(177, 176, 176)">
仅支持.jpg .png格式文件1MB
</p>
</el-form-item>
</el-form-item>
<el-form-item prop="payModel" label="收款方式">
<el-select v-model="recharge.payModel" placeholder="请选择" style="width: 300px">
<el-option v-for="item in payModel" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item prop="payTime" label="交款时间">
<!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
<el-date-picker v-model="recharge.payTime" type="datetime" style="width: 300px" />
</el-form-item>
<el-form-item prop="voucher" label="交款凭证" style="margin-bottom: 5px">
<el-upload :http-request="customUpload" class="avatar-uploader" :show-file-list="false"
:before-upload="beforeAvatarUpload" style="width: 100px; height: 115px">
<img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 100px; height: 115px" />
<el-icon v-else class="avatar-uploader-icon" style="width: 100px; height: 100px">
<Plus />
</el-icon>
</el-upload>
<p style="margin-left: 10px; color: rgb(177, 176, 176)">
仅支持.jpg .png格式文件1MB
</p>
</el-form-item>
<el-form-item prop="remark" label="备注">
<el-input v-model="recharge.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<el-button @click="deleteRecharge" style="margin-left: 220px;margin-top:20px" type="success">重置</el-button>
<el-button type="primary" style="margin-top:20px" :disabled="addDisabled" @click="addBefore"> 提交</el-button>
</el-form>
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" style="max-width: 800px" class="beautiful">
<el-form :model="user" label-width="auto" style="max-width: 800px" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<!-- 第一行姓名 + 历史金币 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名">
<p>{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{
user.nowSumGold
}}</span>
</el-form-item>
<!-- 金币详情独立显示 -->
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
user.nowPermanentGold
}};
免费金币:{{ user.nowFreeGold }};
任务金币:{{ user.nowTaskGold }})</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行精网号 + 当前金币独立行 -->
<el-row>
<el-col :span="9">
<el-form-item label="精网号">
<p>{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="充值次数">
<p style="color: #2fa1ff">{{ user.rechargeNum }}</p>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行首次充值日期 + 充值次数 -->
<el-row>
<el-col :span="9">
<el-form-item label="首次充值日期" >
<p v-if="user.firstRecharge">
{{ moment(user.firstRecharge).format('YYYY-MM-DD HH:mm:ss') }}
</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.consumeNum }}</p>
</el-form-item>
</el-col>
</el-row>
<!-- 第四行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="所属门店">
<p>{{ user.market }}</p>
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="remark" label="备注">
<el-input v-model="recharge.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<el-button @click="deleteRecharge" style="margin-left: 220px;margin-top:20px" type="success">重置</el-button>
<el-button type="primary" style="margin-top:20px" :disabled="addDisabled" @click="addBefore"> 提交</el-button>
</el-form>
</el-card>
</div>
<div class="right">
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" style="max-width: 800px" class="beautiful">
<el-form :model="user" label-width="auto" style="min-width: 650px" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<!-- 第一行姓名 + 历史金币 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名">
<p>{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{
user.nowSumGold
}}</span>
</el-form-item>
<!-- 金币详情独立显示 -->
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
user.nowPermanentGold
}};
免费金币:{{ user.nowFreeGold }};
任务金币:{{ user.nowTaskGold }})</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行精网号 + 当前金币独立行 -->
<el-row>
<el-col :span="9">
<el-form-item label="精网号">
<p>{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="充值次数">
<p style="color: #2fa1ff">{{ user.rechargeNum }}</p>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行首次充值日期 + 充值次数 -->
<el-row>
<el-col :span="9">
<el-form-item label="首次充值日期">
<p v-if="user.firstRecharge">
{{ moment(user.firstRecharge).format('YYYY-MM-DD HH:mm:ss') }}
</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.consumeNum }}</p>
</el-form-item>
</el-col>
</el-row>
<!-- 第四行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="所属门店">
<p>{{ user.market }}</p>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</div>
@ -901,11 +906,37 @@ onMounted(() => {
</div>
</template>
<style scoped>
<style scoped lang="scss">
.userAndForm {
width: 100%;
height: 100%;
display: flex;
align-items: center;
.left {
width: 35%;
display: flex;
.add-form {
width: 100%;
margin-top: 50px;
}
}
.right {
flex: 1;
margin-left: 20px;
display: flex;
.beautiful {
width: 90%;
display: flex;
justify-content: center;
align-items: center;
padding: 0 10px;
}
}
}
p {
@ -917,22 +948,6 @@ p {
margin-left: auto;
}
.el-form-item {
margin-left: 50px;
}
.add-form {
margin-top: 50px;
max-width: 50%;
float: left;
}
.beautiful {
flex: 1;
float: right;
margin-left: 150px;
}
.field-label {
font-size: 14px;
color: #606266;
@ -950,6 +965,7 @@ p {
justify-content: center;
gap: 12px;
}
/* 上传图片的格式 */
.avatar-uploader .avatar {
width: 50px;

360
src/views/workspace/index.vue

@ -1,148 +1,136 @@
<template>
<el-row>
<!-- 数据总览卡片 -->
<el-col :span="4" style="padding-right: 10px;">
<el-card class="center-card margin-bottom">数据总览</el-card>
</el-col>
<!-- 最后更新时间 -->
<el-col :span="18" style="display: flex; align-items: center; font-size: 18px">
<div class="top">
<el-card style="width:20%" class="center-card">数据总览</el-card>
<span class="text">
最后更新时间{{
workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据'
}}
</el-col>
</el-row>
</span>
</div>
<el-row :gutter="10">
<div class="card">
<!-- 第一个卡片 -->
<el-col :span="6">
<el-card class="card-item">
<template #header>
<div class="card-header">
<div class="card-title">当前金币余量</div>
<div>
<span style="font-weight: bold">{{ currentGold / 100 }}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;较前一日
{{ dailyChange / 100 }}
<template v-if="dailyChange > 0">
<el-icon style="color:red">
<ArrowUpBold/>
</el-icon>
</template>
<template v-else-if="dailyChange < 0">
<el-icon style="color:forestgreen">
<ArrowDownBold/>
</el-icon>
</template>
<template v-else>
<el-icon style="color:grey">
<SemiSelect/>
</el-icon>
</template>
</div>
</div>
</template>
<el-card class="card-item">
<template #header>
<div class="card-title">当前金币余量</div>
<div>
<div class="margin-bottom">永久金币{{ currentPermanent / 100 }}</div>
<div class="margin-bottom">免费金币{{ currentFree / 100 }}</div>
<div class="margin-bottom">[六月到期|{{ currentFreeJune / 100 }}]&nbsp;&nbsp;
[十二月到期|{{ currentFreeDecember / 100 }}]
</div>
<div>任务金币{{ currentTask / 100 }}</div>
</div>
</el-card>
</el-col>
<!-- 第二个卡片 -->
<el-col :span="6">
<el-card class="card-item">
<div class="card-title">全年累计充值金币数</div>
<div class="card-title">{{ yearlyRecharge / 100 }}</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div class="center-card">折合新币累计金额:{{ yearlyMoney / 100 }}</div>
<template #footer>
<el-col class="margin-bottom center-card">昨日新增{{ recharge / 100 }}</el-col>
<el-col class="margin-bottom center-card">其中充值{{ money / 100 }}</el-col>
</template>
</el-card>
</el-col>
<!-- 第三个卡片 -->
<el-col :span="6">
<el-card class="card-item">
<div class="card-title">全年累计消费金币数</div>
<div class="card-title">{{ yearlyReduce / 100 }}</div>
<div class="center-card">消费{{ yearlyConsume / 100 }}</div>
<div class="center-card">退款{{ yearlyRefund / 100 }}</div>
<template #footer>
<div></div>
<div class="margin-bottom center-card">昨日新增消费{{ dailyConsume / 100 }}</div>
<div class="margin-bottom center-card">昨日新增消耗{{ dailyReduce / 100 }}</div>
<div class="margin-bottom center-card">昨日新增退款{{ dailyRefund / 100 }}</div>
</template>
</el-card>
</el-col>
<!-- 第四个卡片 -->
<el-col :span="6">
<el-card class="card-item">
<el-col class="card-title">全年累计充值人头数</el-col>
<el-col class="card-title">{{ yearlyRechargeNum }}</el-col>
<el-col class="center-card">周同比:{{ sumWow }}%&nbsp;&nbsp;&nbsp;&nbsp;
<template v-if="sumWow > 0">
<span style="font-weight: bold">{{ currentGold / 100
}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;较前一日
{{ dailyChange / 100 }}
<template v-if="dailyChange > 0">
<el-icon style="color:red">
<ArrowUpBold/>
<ArrowUpBold />
</el-icon>
</template>
<template v-else-if="sumWow < 0">
<template v-else-if="dailyChange < 0">
<el-icon style="color:forestgreen">
<ArrowDownBold/>
<ArrowDownBold />
</el-icon>
</template>
<template v-else>
<el-icon style="color:grey">
<SemiSelect/>
</el-icon>
</template>
</el-col>
<el-col class="center-card">日环比:{{ sumDaily }}%&nbsp;&nbsp;&nbsp;&nbsp;
<template v-if="sumDaily > 0">
<el-icon style="color:red">
<ArrowUpBold/>
</el-icon>
</template>
<template v-else-if="sumDaily < 0">
<el-icon style="color:forestgreen">
<ArrowDownBold/>
<SemiSelect />
</el-icon>
</template>
<template v-else>
<el-icon style="color:grey">
<SemiSelect/>
</el-icon>
</template>
</el-col>
<template #footer>
<el-col class="margin-bottom center-card">昨日充值人数{{ ydayRechargeNum }}</el-col>
<el-col class="margin-bottom center-card">其中首充{{ firstRecharge }}</el-col>
</div>
</template>
<div>
<div class="margin-bottom">永久金币{{ currentPermanent / 100 }}</div>
<div class="margin-bottom">免费金币{{ currentFree / 100 }}</div>
<div class="margin-bottom">[六月到期|{{ currentFreeJune / 100 }}]&nbsp;&nbsp;
[十二月到期|{{ currentFreeDecember / 100 }}]
</div>
<div>任务金币{{ currentTask / 100 }}</div>
</div>
</el-card>
<!-- 第二个卡片 -->
<el-card class="card-item">
<div class="card-title">全年累计充值金币数</div>
<div class="card-title">{{ yearlyRecharge / 100 }}</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div class="center-card">折合新币累计金额:{{ yearlyMoney / 100 }}</div>
<template #footer>
<el-col class="margin-bottom center-card">昨日新增{{ recharge / 100 }}</el-col>
<el-col class="margin-bottom center-card">其中充值{{ money / 100 }}</el-col>
</template>
</el-card>
<!-- 第三个卡片 -->
<el-card class="card-item">
<div class="card-title">全年累计消费金币数</div>
<div class="card-title">{{ yearlyReduce / 100 }}</div>
<div class="center-card">消费{{ yearlyConsume / 100 }}</div>
<div class="center-card">退款{{ yearlyRefund / 100 }}</div>
<template #footer>
<div></div>
<div class="margin-bottom center-card">昨日新增消费{{ dailyConsume / 100 }}</div>
<div class="margin-bottom center-card">昨日新增消耗{{ dailyReduce / 100 }}</div>
<div class="margin-bottom center-card">昨日新增退款{{ dailyRefund / 100 }}</div>
</template>
</el-card>
<!-- 第四个卡片 -->
<el-card class="card-item">
<el-col class="card-title">全年累计充值人头数</el-col>
<el-col class="card-title">{{ yearlyRechargeNum }}</el-col>
<el-col class="center-card">周同比:{{ sumWow }}%&nbsp;&nbsp;&nbsp;&nbsp;
<template v-if="sumWow > 0">
<el-icon style="color:red">
<ArrowUpBold />
</el-icon>
</template>
</el-card>
</el-col>
</el-row>
<el-card style="margin-top: 20px">
<el-row>
<el-col>
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
<el-tab-pane label="金币充值" name="recharge"></el-tab-pane>
<el-tab-pane label="金币消费" name="consume"></el-tab-pane>
</el-tabs>
</el-col>
<div style="margin-top:5px;width:35vw">合计&nbsp;
<template v-else-if="sumWow < 0">
<el-icon style="color:forestgreen">
<ArrowDownBold />
</el-icon>
</template>
<template v-else>
<el-icon style="color:grey">
<SemiSelect />
</el-icon>
</template>
</el-col>
<el-col class="center-card">日环比:{{ sumDaily }}%&nbsp;&nbsp;&nbsp;&nbsp;
<template v-if="sumDaily > 0">
<el-icon style="color:red">
<ArrowUpBold />
</el-icon>
</template>
<template v-else-if="sumDaily < 0">
<el-icon style="color:forestgreen">
<ArrowDownBold />
</el-icon>
</template>
<template v-else>
<el-icon style="color:grey">
<SemiSelect />
</el-icon>
</template>
</el-col>
<template #footer>
<el-col class="margin-bottom center-card">昨日充值人数{{ ydayRechargeNum }}</el-col>
<el-col class="margin-bottom center-card">其中首充{{ firstRecharge }}</el-col>
</template>
</el-card>
</div>
<div class="graph">
<el-card style="width:100%;">
<div>
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
<el-tab-pane label="金币充值" name="recharge"></el-tab-pane>
<el-tab-pane label="金币消费" name="consume"></el-tab-pane>
</el-tabs>
</div>
<div class="condition">
<div style="width:44%;background-color: antiquewhite;">合计&nbsp;
永久金币 {{ activeTab === 'recharge' ? sumRechargePermanent / 100 : sumConsumePermanent / 100 }}&nbsp;&nbsp;
免费金币 {{ activeTab === 'recharge' ? sumRechargeFree / 100 : sumConsumeFree / 100 }}&nbsp;&nbsp;
任务金币 {{ activeTab === 'recharge' ? sumRechargeTask / 100 : sumConsumeTask / 100 }}
</div>
<div @change="handleDatePickerChange" style="width:20vw">
<div @change="handleDatePickerChange" style="width:24%;background-color: aqua;">
<el-button @click="getYes()" :type="activeTimeRange === 'yes' ? 'primary' : ''">昨天
</el-button>
<el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''">今天
@ -154,26 +142,19 @@
<el-button @click="getYear()" :type="activeTimeRange === 'year' ? 'primary' : ''">本年
</el-button>
</div>
<div style="width:25vw">
<div style="width:31%;background-color: bisque;">
<el-date-picker v-model="dateRange" type="datetimerange" range-separator="" start-placeholder="开始时间"
end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss" style="width:20vw"
value-format="YYYY-MM-DD HH:mm:ss"
:default-time="defaultTime" :disabled-date="disabledDate"
/>
end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss" style="width:20vw" value-format="YYYY-MM-DD HH:mm:ss"
:default-time="defaultTime" :disabled-date="disabledDate" />
<el-button type="primary" style="margin-left: 5px" @click="getChartData">查询</el-button>
</div>
</el-row>
<el-row :gutter="20" style="margin-top: 20px">
<el-col :span="18">
<div class="bar">
<div ref="chartRef" style="width: 100%; height: 400px"></div>
</div>
</el-col>
<el-col :span="6">
<el-card class="rank-card" style="width: 100%; height: 100%">
<div class="card-large margin-bottom">金币{{ activeTab === 'recharge' ? '充值' : '消费' }}排名</div>
</div>
<div class="graph-content">
<div ref="chartRef" class="left"></div>
<div class="right">
<el-card>
<div class="card-large">金币{{ activeTab === 'recharge' ? '充值' : '消费' }}排名</div>
<el-select v-model="selectedType" style="width: 100%; margin-bottom: 15px">
<el-option label="全部类型" value="all"></el-option>
<el-option label="永久金币" value="permanent"></el-option>
@ -194,22 +175,22 @@
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
</div>
</div>
</el-card>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import {ref, onMounted, nextTick, watch, onUnmounted} from 'vue'
import { ref, onMounted, nextTick, watch, onUnmounted } from 'vue'
import API from '@/util/http'
import {ElMessage} from 'element-plus'
import { ElMessage } from 'element-plus'
import dayjs from 'dayjs';
import utc from 'dayjs-plugin-utc'
dayjs.extend(utc)
import {ArrowUpBold, ArrowDownBold, SemiSelect} from '@element-plus/icons-vue'
import {marketMapping} from "@/utils/marketMap.js";
import { ArrowUpBold, ArrowDownBold, SemiSelect } from '@element-plus/icons-vue'
import { marketMapping } from "@/utils/marketMap.js";
const defaultTime = [
new Date(2000, 1, 1, 0, 0, 0),
@ -326,7 +307,7 @@ const getToday = function () {
//
const getWeek = function () {
const today = dayjs()
const startTime =((today.startOf('week').add(1, 'day')).format('YYYY-MM-DD HH:mm:ss'))
const startTime = ((today.startOf('week').add(1, 'day')).format('YYYY-MM-DD HH:mm:ss'))
const endTime = (today.endOf('week').add(1, 'day')).format('YYYY-MM-DD HH:mm:ss')
// const endTime = today.add(1, 'week').startOf('week').add(1, 'day').format('YYYY-MM-DD HH:mm:ss')
dateRange.value = [startTime, endTime]
@ -629,7 +610,7 @@ const updateChart = (chartData) => {
type: 'bar',
stack: 'recharge',
data: chartData.rechargePermanent,
itemStyle: {color: '#5470c6'},
itemStyle: { color: '#5470c6' },
barWidth: 30
},
{
@ -637,7 +618,7 @@ const updateChart = (chartData) => {
type: 'bar',
stack: 'recharge',
data: chartData.rechargeFree,
itemStyle: {color: '#91cc75'},
itemStyle: { color: '#91cc75' },
barWidth: 30
},
{
@ -645,7 +626,7 @@ const updateChart = (chartData) => {
type: 'bar',
stack: 'recharge',
data: chartData.rechargeTask,
itemStyle: {color: '#fac858'},
itemStyle: { color: '#fac858' },
barWidth: 30
}
]
@ -657,7 +638,7 @@ const updateChart = (chartData) => {
type: 'bar',
stack: 'consume',
data: chartData.consumePermanent,
itemStyle: {color: '#5470c6'},
itemStyle: { color: '#5470c6' },
barWidth: 30
},
{
@ -665,7 +646,7 @@ const updateChart = (chartData) => {
type: 'bar',
stack: 'consume',
data: chartData.consumeFree,
itemStyle: {color: '#91cc75'},
itemStyle: { color: '#91cc75' },
barWidth: 30
},
{
@ -673,7 +654,7 @@ const updateChart = (chartData) => {
type: 'bar',
stack: 'consume',
data: chartData.consumeTask,
itemStyle: {color: '#fac858'},
itemStyle: { color: '#fac858' },
barWidth: 30
}
]
@ -754,7 +735,7 @@ const handleTabChange = () => {
const getAdminData = async function () {
try {
const result = await API({url: '/admin/userinfo', data: {}})
const result = await API({ url: '/admin/userinfo', data: {} })
adminData.value = result
console.log('用户信息', adminData.value)
} catch (error) {
@ -764,7 +745,7 @@ const getAdminData = async function () {
//
const getCardData = async () => {
try {
const response = await API({url: '/workbench/getCard', data: {}})
const response = await API({ url: '/workbench/getCard', data: {} })
workDataUpdateTime.value = response.updateTime
//
sumWow.value = response.sumWow.toFixed(2)
@ -806,6 +787,56 @@ onUnmounted(() => {
</script>
<style scoped>
.top {
height: 5.5%;
width:100%;
display: flex;
margin-bottom: 0.2%;
.text{
margin-left:0.2%;
width:50%;
display: flex;
align-items: center;
font-size: 18px;
}
}
.card {
height: 28%;
display: flex;
justify-content: center;
}
.graph {
width: 100%;
display: flex;
height: 64%;
background-color: aqua;
.condition {
width: 100%;
height: 1%;
display: flex;
align-items: center;
}
.graph-content {
flex: 1;
height: auto;
display: flex;
.left {
width: 70%;
height: auto;
}
.right {
flex: 1;
padding: 0.5% 2%;
}
}
}
.center-card {
display: flex;
justify-content: center;
@ -813,14 +844,16 @@ onUnmounted(() => {
}
.margin-bottom {
margin-bottom: 5px;
margin-bottom: 0.5%;
}
.card-item {
height: 260px;
width: 25%;
height: 98%;
display: flex;
flex-direction: column;
justify-content: center;
margin-right: 0.25%;
}
.card-title {
@ -831,10 +864,6 @@ onUnmounted(() => {
align-items: center;
}
.rank-card {
height: 500px;
}
.card-large {
font-weight: bold;
font-size: 16px;
@ -842,13 +871,6 @@ onUnmounted(() => {
margin-bottom: 15px;
}
.bar {
background: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
@keyframes spin {
0% {
transform: rotate(0deg);

Loading…
Cancel
Save