master
xy 3 years ago
parent df6df947f2
commit 8b4a88ce20

@ -0,0 +1,13 @@
import request from "@/utils/request";
import {getToken} from "@/utils/auth";
export function login (params) {
return request({
headers: {
['Authorization']: 'Bearer' + getToken('ReceptionTokenKey')
},
url: '/api/user/login',
method: 'get',
params
})
}

@ -0,0 +1,17 @@
import request from "@/utils/request";
export function day (params) {
return request({
method: 'get',
url: '/api/admin/chart/day',
params
})
}
export function month (params) {
return request({
method: 'get',
url: '/api/admin/chart/month',
params
})
}

@ -3,8 +3,9 @@ import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import {getToken, setToken} from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
import { login } from "@/api/reception/index"
NProgress.configure({ showSpinner: false }) // NProgress Configuration
@ -18,7 +19,22 @@ router.beforeEach(async(to, from, next) => {
document.title = getPageTitle(to.meta.title)
if (/^\/index\/.*/.test(to.path)) {
next()
if (getToken('RecptionTokenKey')) {
next()
} else {
if (to.query.code) {
login({
code: to.query.code
}).then(res => {
setToken(res.access_token,'RecoveryTokenKey')
next()
})
} else {
let redirectUri = encodeURIComponent(window.location.href)
window.location.href = `https://api.weishao.com.cn/oauth/authorize?client_id=d05e4c9d07f705ef&redirect_uri=${redirectUri}&response_type=code&scope=base_api&state=wyd`
}
}
return
}
// determine whether the user has logged in

@ -133,9 +133,9 @@ export function generaMenu(routes, data) {
}
}, ]
}
if (item.children) {
generaMenu(menu.children, item.children)
}
// if (item.children) {
// generaMenu(menu.children, item.children)
// }
routes.push(menu)
} else {
const menu = {

@ -1,15 +1,15 @@
import Cookies from 'js-cookie'
const TokenKey = 'weiyuan_doc_token'
export function getToken() {
return Cookies.get(TokenKey)
const RecptionTokenKey = 'weiyuan_doc_reception_token'
export function getToken(key = TokenKey) {
return Cookies.get(key)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
export function setToken(token, key = TokenKey) {
return Cookies.set(key, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
export function removeToken(key = TokenKey) {
return Cookies.remove(key)
}

@ -7,7 +7,7 @@ import {
import store from '@/store'
import {
getToken
} from '@/utils/auth'
} from '@/utils/auth';
let loading ;
// create an axios instance
@ -30,7 +30,7 @@ service.interceptors.request.use(
}
// do something before request is sent
if (store.getters.token) {
if (store.getters.token && !config.headers['Authorization']) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation

@ -0,0 +1,48 @@
<template>
<div>
<el-select multiple collapse-tags value-key="id" style="width: 100%" v-model="value" @change="change">
<el-option v-for="item in tags" :value="item.mingcheng" :label="item.mingcheng"></el-option>
</el-select>
</div>
</template>
<script>
import { index } from "@/api/system/baseForm"
export default {
props: {
fieldInfo: Object,
form: Object
},
data() {
return {
value: '',
tags: [],
}
},
methods: {
async getTags () {
const res = await index({
page: 1,
page_size: 9999,
table_name: 'tags',
})
this.tags = res.data
},
change (e) {
this.$emit('update', this.value.toString())
}
},
computed: {},
watch: {
'form.biaoqian' (newVal) {
this.value = newVal.split(',')
}
},
created() {
this.getTags()
}
}
</script>
<style scoped lang="scss">
</style>

@ -369,8 +369,6 @@ export default {
},
submit() {
console.log(this.form)
return
if (this.type === "add") {
if (this.form.hasOwnProperty("id")) {
delete this.form.id;
@ -399,22 +397,25 @@ export default {
this.formInfo.forEach((info) => {
if (info._relations?.link_relation === 'newHasMany' || info._relations?.link_relation === 'hasMany') {
if (info.edit_input === 'files') {
copyForm[info._relations.link_with_name] = this.file[info.field].map(i => i?.response);
copyForm[info._relations.link_with_name] = this.file[info.field]?.map(i => i?.response);
} else {
copyForm[info._relations.link_with_name] = copyForm[info.field]
copyForm[info._relations.link_with_name] = copyForm[info.field]?.map( i => info._params.find(param => param[info._relations?.foreign_key] === i))
}
delete copyForm[info.field]
}
if (info._relations?.link_relation === 'newHasOne' || info._relations?.link_relation === 'hasOne') {
if (info.edit_input === 'file') {
//this.form[info._relations.link_with_name] =
copyForm[info._relations.link_with_name] = this.file[info.field]?.map(i => i?.response);
} else {
copyForm[info._relations.link_with_name] = info._params.find(param => param[info._relations?.foreign_key] === copyForm[info.field])
}
delete copyForm[info.field]
}
if (!copyForm[info._relations?.link_with_name]) {
delete copyForm[info._relations?.link_with_name]
}
// if (info._relations?.link_with_name) {
// if (info.edit_input === "files" || info.edit_input === "file") {
// this.form[info._relations.link_with_name] = this.file[info.field].map(i => i?.response);

@ -23,13 +23,16 @@
</el-descriptions-item>
</template>
</el-descriptions>
<Table style="margin: 0 10px;" stripe :loading="isLoading" :data="logs" :columns="logTable">
</Table>
</template>
</el-drawer>
</div>
</template>
<script>
import { show } from "@/api/system/baseForm";
import { show, index } from "@/api/system/baseForm";
import descriptionItem from "@/views/component/descriptionItem.vue";
export default {
@ -49,6 +52,32 @@ export default {
isShow: false,
detail: {},
isLoading: false,
logs: [],
logTable: [
{
key: 'created_at',
title: '日期',
width: 200
},
{
key: 'neirong',
title: '内容',
align: 'left',
minWidth: 220
},
{
key: 'kehuduanbiaozhi',
title: 'ip',
width: 140
},
{
key: 'liulanqi',
title: '浏览器',
minWidth: 160,
}
]
};
},
methods: {
@ -68,6 +97,23 @@ export default {
getId() {
return this.id;
},
async getLogs() {
const res = await index({
table_name: 'material_logs',
page: 1,
page_size: 9999,
filter: [
{
key: 'ziliaoguanlian',
value: this.id,
op: 'eq'
}
]
})
this.logs = res.data
console.log(123,res)
}
},
computed: {
contentFormat() {
@ -106,6 +152,8 @@ export default {
).then((res) => {
this.detail = res;
});
this.getLogs();
}
},
},
@ -117,4 +165,9 @@ export default {
.btns {
margin: 0 10px 12px 10px;
}
::v-deep .el-drawer .el-drawer__body {
padding-bottom: 20px;
}
</style>

@ -0,0 +1,175 @@
<template>
<div>
<el-drawer
ref="elDrawer"
:visible.sync="isShow"
size="80%"
direction="rtl"
>
<template #title>
<el-button>审核</el-button>
</template>
<template>
<el-descriptions
size="medium"
direction="vertical"
:column="3"
:labelStyle="{ 'font-weight': '600', width: '33%' }"
:content-style="{ width: '33%' }"
border
style="margin: 20px 10px"
>
<template v-for="info in formInfo">
<el-descriptions-item :label="info.name">
<descriptionItem :info="info" :detail="detail"></descriptionItem>
</el-descriptions-item>
</template>
</el-descriptions>
<Table style="margin: 0 10px;" stripe :loading="isLoading" :data="logs" :columns="logTable">
</Table>
</template>
</el-drawer>
</div>
</template>
<script>
import { show, index } from "@/api/system/baseForm";
import descriptionItem from "@/views/component/descriptionItem.vue";
export default {
components: {
descriptionItem
},
props: {
formInfo: {
type: Array,
default: () => [],
},
tableName: String,
},
data() {
return {
id: "",
isShow: false,
detail: {},
isLoading: false,
logs: [],
logTable: [
{
key: 'created_at',
title: '日期',
width: 200
},
{
key: 'neirong',
title: '内容',
align: 'left',
minWidth: 220
},
{
key: 'kehuduanbiaozhi',
title: 'ip',
width: 140
},
{
key: 'liulanqi',
title: '浏览器',
minWidth: 160,
}
]
};
},
methods: {
show() {
this.isShow = true;
},
hidden() {
this.isShow = false;
},
setId(id) {
if (typeof id == "number") {
this.id = id;
} else {
console.error("error typeof id: " + typeof id);
}
},
getId() {
return this.id;
},
async getLogs() {
const res = await index({
table_name: 'material_logs',
page: 1,
page_size: 9999,
filter: [
{
key: 'ziliaoguanlian',
value: this.id,
op: 'eq'
}
]
})
this.logs = res.data
console.log(123,res)
}
},
computed: {
contentFormat() {
return function (i) {
if (i.parameter_id) {
return this.detail[i.link_with_name]?.value;
}
if (i.link_table_name) {
if (i.link_relation === "hasOne") {
return (
this.detail[i.link_with_name]?.name ||
this.detail[i.link_with_name]?.no ||
this.detail[i.link_with_name]?.value
);
}
if (i.link_relation === "hasMany") {
return this.detail[i.link_with_name]
?.map((o) => o?.name || o?.no || o?.value)
?.toString();
}
}
return this.detail[i.field]
};
},
},
watch: {
isShow(newVal) {
if (newVal) {
show(
{
table_name: this.tableName,
id: this.id,
},
true
).then((res) => {
this.detail = res;
});
this.getLogs();
}
},
},
mounted() {},
};
</script>
<style scoped lang="scss">
.btns {
margin: 0 10px 12px 10px;
}
::v-deep .el-drawer .el-drawer__body {
padding-bottom: 20px;
}
</style>

@ -0,0 +1,21 @@
<template>
<div>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {},
computed: {},
render(h) {
retrun
}
}
</script>
<style scoped lang="scss">
</style>

@ -184,7 +184,7 @@
/>
</template>
<el-button
v-if="index !== 0"
v-if="index !== 1"
size="small"
type="danger"
icon="el-icon-delete"
@ -238,7 +238,7 @@
</div>
<xy-table
:btn-width="200"
:btn-width="220"
:auths="auths_auth_mixin"
:delay-req="true"
:destroy-action="destroy"
@ -262,6 +262,18 @@
}
"
>
<template #submit="scope">
<template v-if="scope.row.zhuangtai == 0">
<Button type="primary"
size="small"
@click="submit(scope, 1)">提交</Button>
</template>
<template v-else>
<Button type="primary"
size="small"
@click="submit(scope, 0)">下架</Button>
</template>
</template>
</xy-table>
<dialoger
@ -273,6 +285,9 @@
<template #fujian="{ fieldInfo, form, file }" v-if="$route.meta.params && $route.meta.params.type == 1">
<flow :field-info="fieldInfo" :form="form" :file="file" @update="val => form['fujian'] = val"></flow>
</template>
<template #biaoqian="{ fieldInfo, form, file }">
<biaoqian :field-info="fieldInfo" :form="form" @update="val => form['biaoqian'] = val"></biaoqian>
</template>
</dialoger>
<drawer
:table-name="customForm.tableName"
@ -291,7 +306,7 @@
<script>
import { index as fieldIndex } from "@/api/system/customFormField";
import { authMixin } from "@/mixin/authMixin";
import { index, destroy } from "@/api/system/baseForm";
import { index, destroy, save } from "@/api/system/baseForm";
import { op } from "@/const/op";
import { download } from "@/utils/downloadRequest";
import { getparameter } from "@/api/system/dictionary";
@ -306,7 +321,9 @@ import LxHeader from "@/components/LxHeader/index.vue";
import headerContent from "@/components/LxHeader/XyContent.vue";
import drawer from "@/views/component/drawer.vue";
import imports from "./imports.vue";
import flow from "@/views/flow/flow.vue"
import flow from "@/views/flow/flow.vue";
import biaoqian from "./biaoqian.vue";
import fujian from "./fujian.vue";
export default {
components: {
LxHeader,
@ -315,7 +332,9 @@ export default {
drawer,
imports,
flow
flow,
biaoqian,
fujian
},
mixins: [authMixin],
provide: {
@ -405,6 +424,21 @@ export default {
target.value = `${temp ? temp : ""},${e}`;
},
//
submit (scope, setType) {
save(Object.assign( deepCopy(scope.row), { 'zhuangtai': setType,'table_name': this.customForm.tableName })).then(res => {
this.$message({
type: 'success',
message: '操作成功'
})
this.$refs['xyTable'].getTableData()
})
},
async getFormDetail() {
if (this.$route.meta.params?.custom_form) {
let decode = decodeURIComponent(this.$route.meta.params?.custom_form);
@ -430,6 +464,13 @@ export default {
['admins',[]]
])
let { fields, relation } = res;
let fieldRes = await fieldIndex({
page: 1,
page_size: 999,
custom_form_id: this.customForm.customFormId,
sort_name: 'sort',
sort_type: 'asc'
},false)
if (
!fields ||
!relation ||
@ -438,7 +479,7 @@ export default {
) {
throw new Error("fields或relation格式错误");
}
fields.forEach((i, index) => {
fieldRes?.data?.forEach((i, index) => {
i._relations = relation.find((j) => j.local_key === i.field);
if (i.select_item && typeof i.select_item === 'object') {
let keys = Object.keys(i.select_item)
@ -470,7 +511,7 @@ export default {
}
}
});
this.form = fields;
this.form = fieldRes?.data || [];
this.table = this.form
?.filter((i) => i.list_show)
.map((i) => {
@ -561,21 +602,21 @@ export default {
computed: {
columnArrTest() {
return function (field) {
return this.form.find((i) => i.field === field)
return this.form?.find((i) => i.field === field)
? this.form.find((i) => i.field === field).search_input === "checkbox" || this.form.find((i) => i.field === field).search_input === "radio"
: false;
};
},
getColumnField() {
return function (field) {
return this.form.find((i) => i.field === field)
return this.form?.find((i) => i.field === field)
? this.form.find((i) => i.field === field)
: {};
};
},
getColumnParams() {
return function (field) {
return this.form.find((i) => i.field === field)
return this.form?.find((i) => i.field === field)
? this.form.find((i) => i.field === field)._params
: [];
};

@ -0,0 +1,657 @@
<template>
<div>
<!-- 查询配置 -->
<div>
<div ref="lxHeader">
<LxHeader
icon="md-apps"
:text="$route.meta.title"
style="margin-bottom: 10px; border: 0px; margin-top: 15px"
>
<div slot="content"></div>
<slot>
<header-content :auths="auths_auth_mixin">
<template #search>
<div style="display: flex">
<Select
v-model="select.filter[0].key"
style="width: 100px"
placeholder="搜索条目"
>
<Option
v-for="item in form"
:key="item.id"
:value="item.field"
>{{ item.name }}</Option
>
</Select>
<Select
v-model="select.filter[0].op"
style="width: 100px; margin-left: 10px"
placeholder="搜索条件"
>
<Option
v-for="item in op"
:key="item.value"
:value="item.value"
>{{ item.label }}</Option
>
</Select>
<template
v-if="
select.filter[0].op !== 'range' &&
!columnArrTest(select.filter[0].key)
"
>
<Input
v-model="select.filter[0].value"
style="width: 150px; margin-left: 10px"
placeholder="请填写关键词"
/>
</template>
<template
v-else-if="
select.filter[0].op !== 'range' &&
columnArrTest(select.filter[0].key)
"
>
<Select
v-model="select.filter[0].value"
style="width: 150px; margin-left: 10px"
placeholder="请选择关键词"
>
<Option
v-for="item in getColumnParams(select.filter[0].key)"
:key="item.id"
:value="getColumnField(select.filter[0].key)._relations ? item[getColumnField(select.filter[0].key)._relations.foreign_key] : item.value"
>{{
item.key || item.value || item.name || item.no || item.mingcheng || item.id
}}</Option
>
</Select>
</template>
<template v-else>
<Input
:value="select.filter[0].value.split(',')[1]"
style="width: 150px; margin-left: 10px"
placeholder="范围开始关键词"
@input="(e) => inputStartHandler(e, select.filter[0])"
/>
<span
style="
margin-left: 10px;
display: flex;
align-items: center;
"
></span
>
<Input
:value="select.filter[1].value.split(',')[1]"
style="width: 150px; margin-left: 10px"
placeholder="范围结束关键词"
@input="(e) => inputEndHandler(e, select.filter[0])"
/>
</template>
<Button
style="margin-left: 10px"
type="primary"
@click="$refs['xyTable'].getTableData(true)"
>查询</Button
>
<xy-selectors
style="margin-left: 10px"
@reset="reset"
@search="$refs['xyTable'].getTableData(true)"
>
<template>
<div class="select">
<div
class="select__item"
v-for="(item, index) in select.filter"
:key="`${item.value}-${index}`"
>
<p>条件{{ index + 1 }}</p>
<Select
v-model="item.key"
style="width: 100px"
placeholder="搜索条目"
>
<Option
v-for="item in form"
:key="item.id"
:value="item.field"
>{{ item.name }}</Option
>
</Select>
<Select
v-model="item.op"
style="width: 100px; margin-left: 10px"
placeholder="搜索条件"
>
<Option
v-for="item in op"
:key="item.value"
:value="item.value"
>{{ item.label }}</Option
>
</Select>
<template
v-if="
item.op !== 'range' && !columnArrTest(item.key)
"
>
<Input
v-model="item.value"
style="width: 150px; margin-left: 10px"
placeholder="请填写关键词"
/>
</template>
<template
v-else-if="
item.op !== 'range' && columnArrTest(item.key)
"
>
<Select
v-model="item.value"
style="width: 150px; margin-left: 10px"
placeholder="请选择关键词"
>
<Option
v-for="item in getColumnParams(item.key)"
:key="item.id"
:value="getColumnField(item.key)._relations ? item[getColumnField(item.key)._relations.foreign_key] : item.value"
>{{
item.key || item.value || item.name || item.no || item.mingcheng || item.id
}}</Option
>
</Select>
</template>
<template v-else>
<Input
:value="item.value.split(',')[0]"
style="width: 150px; margin-left: 10px"
placeholder="范围开始关键词"
@input="(e) => inputStartHandler(e, item)"
/>
<span style="margin-left: 10px"></span>
<Input
:value="item.value.split(',')[1]"
style="width: 150px; margin-left: 10px"
placeholder="范围结束关键词"
@input="(e) => inputEndHandler(e, item)"
/>
</template>
<el-button
v-if="index !== 0"
size="small"
type="danger"
icon="el-icon-delete"
circle
style="margin-left: 10px"
@click="select.filter.splice(index, 1)"
></el-button>
</div>
</div>
<div class="add-btn">
<el-button
size="small"
type="primary"
icon="el-icon-plus"
circle
@click="
select.filter.push({ key: '', op: '', value: '' })
"
></el-button>
<span>新增一条</span>
</div>
</template>
</xy-selectors>
</div>
</template>
<template #create>
<Button
type="primary"
@click="
$refs['dialog'].setType('add'), $refs['dialog'].show()
"
>新增</Button
>
</template>
<template #import>
<Button type="primary" @click="$refs['imports'].show()"
>导入</Button
>
</template>
<template #export>
<Button
type="primary"
@click="exportExcel(new Date().getTime().toString())"
>导出</Button
>
</template>
</header-content>
</slot>
</LxHeader>
</div>
</div>
<xy-table
:btn-width="210"
:auths="auths_auth_mixin"
:delay-req="true"
:destroy-action="destroy"
ref="xyTable"
:border="true"
:action="index"
:req-opt="select"
:destroy-req-opt="{ 'table_name': customForm.tableName }"
:table-item="table"
@detail="
(row) => {
$refs['drawer'].setId(row.id);
$refs['drawer'].show();
}
"
@editor="
(row) => {
$refs['dialog'].setId(row.id);
$refs['dialog'].setType('editor');
$refs['dialog'].show();
}
"
>
<template #submit="scope">
<template v-if="scope.row.zhuangtai == 0">
<Button type="primary"
size="small"
@click="submit(scope, 1)">提交</Button>
</template>
<template v-else>
<Button type="primary"
size="small"
@click="submit(scope, 0)">下架</Button>
</template>
</template>
</xy-table>
<dialoger
:table-name="customForm.tableName"
:form-info="form"
ref="dialog"
@refresh="$refs['xyTable'].getTableData()"
>
<template #fujian="{ fieldInfo, form, file }" v-if="$route.meta.params && $route.meta.params.type == 1">
<flow :field-info="fieldInfo" :form="form" :file="file" @update="val => form['fujian'] = val"></flow>
</template>
</dialoger>
<drawer
:table-name="customForm.tableName"
:form-info="form"
ref="drawer"
></drawer>
<imports
:table-name="customForm.tableName"
:form-info="form"
ref="imports"
@refresh="$refs['xyTable'].getTableData()"
></imports>
</div>
</template>
<script>
import { index as fieldIndex } from "@/api/system/customFormField";
import { authMixin } from "@/mixin/authMixin";
import { index, destroy, save } from "@/api/system/baseForm";
import { op } from "@/const/op";
import { download } from "@/utils/downloadRequest";
import { getparameter } from "@/api/system/dictionary";
import { show } from "@/api/system/customForm";
import * as XLSX from "xlsx";
import { saveAs } from "file-saver";
import { listdept } from "@/api/system/department";
import { deepCopy } from "@/utils";
import dialoger from "./dialog.vue";
import LxHeader from "@/components/LxHeader/index.vue";
import headerContent from "@/components/LxHeader/XyContent.vue";
import drawer from "@/views/component/drawer.vue";
import imports from "./imports.vue";
import flow from "@/views/flow/flow.vue"
export default {
components: {
LxHeader,
dialoger,
headerContent,
drawer,
imports,
flow
},
mixins: [authMixin],
provide: {
formStore: () => this.form,
},
data() {
return {
op,
select: {
table_name: "",
filter: [
{
key: "",
op: "",
value: "",
},
],
},
form: [],
table: [],
customForm: {
customFormId: "",
tableName: "",
},
};
},
methods: {
index,
destroy,
download,
reset() {
this.select.filter.splice(2);
this.select.filter[0] = {
key: "leixing",
op: "eq",
value: this.$route.meta.params?.type,
};
this.select.filter[1] = {
key: "",
op: "",
value: "",
};
},
async exportExcel(sheetName) {
const res = await index(
Object.assign(this.select, { page: 1, page_size: 9999 })
);
if (res.data) {
let headers = this.form.map((i) => {
return {
key: i.field,
title: i.name,
};
});
const data = res.data.map((row) =>
headers.map((header) => row[header.key])
);
data.unshift(headers.map((header) => header.title));
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data);
XLSX.utils.book_append_sheet(wb, ws, sheetName);
const wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
`${sheetName}.xlsx`
);
}
},
//target
inputStartHandler(e, target) {
let temp = target?.value.split(",")[1];
target.value = `${e},${temp ? temp : ""}`;
},
inputEndHandler(e, target) {
let temp = target?.value.split(",")[0];
target.value = `${temp ? temp : ""},${e}`;
},
//
submit (scope, setType) {
save(Object.assign( deepCopy(scope.row), { 'zhuangtai': setType,'table_name': this.customForm.tableName })).then(res => {
this.$message({
type: 'success',
message: '操作成功'
})
this.$refs['xyTable'].getTableData()
})
},
async getFormDetail() {
if (this.$route.meta.params?.custom_form) {
let decode = decodeURIComponent(this.$route.meta.params?.custom_form);
try {
let custom_form = JSON.parse(decode);
this.customForm.customFormId = custom_form.custom_form_id;
this.customForm.tableName = custom_form.table_name;
this.select.table_name = custom_form.table_name;
} catch (err) {
console.warn(err);
}
}
const res = await show({ id: this.customForm.customFormId }, false);
//
//
let baseTable = new Map([
['departments', async () => {
const res = await listdept()
return res
}],
['admins',[]]
])
let { fields, relation } = res;
if (
!fields ||
!relation ||
!fields instanceof Array ||
!relation instanceof Array
) {
throw new Error("fields或relation格式错误");
}
fields.forEach((i, index) => {
i._relations = relation.find((j) => j.local_key === i.field);
if (i.select_item && typeof i.select_item === 'object') {
let keys = Object.keys(i.select_item)
i._params = keys.map(key => {
return {
key,
value: i.select_item[key]
}
})
}
if (i.edit_input === 'file' || i.edit_input === 'files') {
return
}
if (i._relations) {
if (baseTable.get(i._relations.link_table_name)) {
baseTable.get(i._relations.link_table_name)().then(res => i._params = res)
} else {
i._params = i._relations.parameter_id
? getparameter({ id: i._relations.parameter_id },false).then((res) => {
i._params = res.detail;
})
: this.index({
table_name: i._relations.link_table_name,
page: 1,
page_size: 9999,
}).then((res) => {
i._params = res.data;
});
}
}
});
let fieldRes = await fieldIndex({
page: 1,
page_size: 999,
custom_form_id: this.customForm.customFormId,
sort_name: 'sort',
sort_type: 'asc'
},false)
this.form = fieldRes?.data || [];
this.table = this.form
?.filter((i) => i.list_show)
.map((i) => {
let linkOb = {};
if (i.edit_input === 'richtext') {
linkOb.customFn = row => {
return (
<el-scrollbar>
<div style={{ 'max-height': '50px' }} domPropsInnerHTML={row[i.field]}></div>
</el-scrollbar>
)
}
}
if (i.select_item && typeof i.select_item === 'object' && !(i.select_item instanceof Array)) {
let keys = Object.keys(i.select_item)
linkOb.customFn = row => {
let paramMap = new Map()
keys.forEach(key => {
paramMap.set(i.select_item[key],key)
})
return (
<span>
{ paramMap.get(row[i.field]?.toString()) }
</span>
)
}
}
if (i._relations) {
let { link_relation, foreign_key, link_with_name } = i._relations
if (link_relation === 'newHasOne' || link_relation === 'hasOne') {
linkOb.customFn = row => {
if (i.edit_input === "file") {
return (
<a
download={row[link_with_name]?.original_name}
href={row[link_with_name]?.url}
>
{row[link_with_name]?.original_name}
</a>
);
} else {
return (
<span>
{ row[link_with_name]?.name ||
row[link_with_name]?.no ||
row[link_with_name]?.value }
</span>
);
}
}
}
if (link_relation === "hasMany" || link_relation === 'newHasMany') {
linkOb.customFn = (row) => {
return (
<div>
{row[link_with_name]?.map((o) => (
<span>{o?.name || o?.no || o?.value}</span>
))}
</div>
);
};
}
}
return Object.assign(
{
prop: i.field,
label: i.name,
width: i.width,
fixed: i.is_fixed,
},
linkOb
);
});
this.table.unshift({
type: "index",
width: 60,
label: "序号",
});
console.log(111,this.form)
},
},
computed: {
columnArrTest() {
return function (field) {
return this.form?.find((i) => i.field === field)
? this.form.find((i) => i.field === field).search_input === "checkbox" || this.form.find((i) => i.field === field).search_input === "radio"
: false;
};
},
getColumnField() {
return function (field) {
return this.form?.find((i) => i.field === field)
? this.form.find((i) => i.field === field)
: {};
};
},
getColumnParams() {
return function (field) {
return this.form?.find((i) => i.field === field)
? this.form.find((i) => i.field === field)._params
: [];
};
},
//TODO:
},
created() {
this.getFormDetail();
},
};
</script>
<style scoped lang="scss">
.select {
&__item {
& > p {
display: inline-block;
width: 80px;
text-align: center;
}
& + div {
margin-top: 6px;
}
}
}
.add-btn {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
& > span {
padding: 0 10px;
}
}
a {
color: red;
text-decoration: none;
transition: all 0.2s;
}
a:hover {
color: red;
text-decoration: underline;
}
</style>

@ -35,6 +35,9 @@ export default {
},
methods: {},
computed: {},
mounted() {
console.log(111,this.$route)
}
}
</script>

@ -0,0 +1,120 @@
<template>
<div>
<lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="访问统计">
<div slot="content"></div>
<slot>
<div>
<el-date-picker
type="month"
size="small"
v-model="select.month"
value-format="yyyy-MM"
style="width: 200px;">
</el-date-picker>
<el-button size="small" type="primary" style="margin-left: 10px;" @click="getData"></el-button>
</div>
</slot>
</lx-header>
<div style="display: flex;margin-top: 20px">
<div v-if="data" class="box">
<div style="border-bottom: 2px solid rgba(200,200,200,0.7);padding-bottom: 20px">
<i class="el-icon-coin"></i>
<span style="font-weight: 600;padding: 0 10px">访问统计</span>
</div>
<div id="doughnut-chart"/>
</div>
</div>
</div>
</template>
<script>
import { month } from "@/api/statics";
import echarts from "echarts";
export default {
data() {
return {
chart: '',
select: {
month: this.$moment(new Date()).format('YYYY-MM')
},
data: {}
}
},
methods: {
init () {
this.chart = echarts.init(document.getElementById('doughnut-chart'))
let colors = ['#00A82A', '#70e1f5', '#ffd194', '#FF6B6B', '#6E48AA', '#4B1248']
let data = []
this.chart.setOption(
{
tooltip: {
trigger: 'item'
},
legend: {
top: '3%',
left: 'center'
},
series: [
{
type: 'pie',
radius: ['46%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '15',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data
}
]
}
)
},
async getData () {
const res = await month(this.select)
console.log(res,111)
this.init()
}
},
computed: {},
created() {
this.getData()
}
}
</script>
<style scoped lang="scss">
.box {
flex: 1;
background: #fff;
border-radius: 10px;
padding: 20px;
margin-right: 40px;
#doughnut-chart {
box-sizing: border-box;
min-height: 240px;
}
}
</style>

@ -0,0 +1,162 @@
<template>
<div>
<lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="日访问统计">
<div slot="content"></div>
<slot>
<div>
<el-date-picker
v-model="value"
type="daterange"
align="center"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
:picker-options="pickerOptions"
@change="pick">
</el-date-picker>
<el-button size="small" type="primary" style="margin-left: 10px;" @click="getData"></el-button>
</div>
</slot>
</lx-header>
<div style="display: flex;margin-top: 20px">
<div v-if="data" class="box">
<div style="border-bottom: 2px solid rgba(200,200,200,0.7);padding-bottom: 20px">
<i class="el-icon-coin"></i>
<span style="font-weight: 600;padding: 0 10px">日访问统计</span>
</div>
<div id="line-chart"/>
</div>
</div>
</div>
</template>
<script>
import { day } from "@/api/statics";
import echarts from 'echarts';
require('echarts/theme/macarons') // echarts theme
export default {
data() {
return {
chart: "",
value: [ this.$moment(new Date()).format('YYYY-MM-DD'), this.$moment(new Date()).format('YYYY-MM-DD')],
select: {
start_date: this.$moment(new Date()).format('YYYY-MM-DD'),
end_date: this.$moment(new Date()).format('YYYY-MM-DD')
},
data: {},
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}]
}
}
},
methods: {
init () {
this.chart = echarts.init(document.getElementById('line-chart'))
let xAxis = [];
for (let key in this.data) {
xAxis.push(this.data[key][0]?.leixing)
}
this.chart.setOption(
{
xAxis: {
type: 'category',
data: xAxis
},
yAxis: {
type: 'value'
},
series: (() => {
let data = []
for (let key in this.data) {
data.push({
data: this.data[key].map(i => i.total),
type: 'line',
smooth: true,
})
}
return data;
})()
}
)
},
pick (e) {
if (e && e.length > 0) {
this.select.start_date = e[0]
this.select.end_date = e[1]
} else {
this.select.start_date = ''
this.select.end_date = ''
}
},
async getData () {
const res = await day(this.select)
this.data = res
this.init();
}
},
computed: {},
created() {
this.getData()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
}
</script>
<style scoped lang="scss">
.box {
flex: 1;
background: #fff;
border-radius: 10px;
padding: 20px;
margin-right: 40px;
#line-chart {
box-sizing: border-box;
min-height: 240px;
}
}
</style>
Loading…
Cancel
Save