diff --git a/.env.development b/.env.development index 34f0084..879d33c 100644 --- a/.env.development +++ b/.env.development @@ -3,6 +3,6 @@ ENV = 'development' # base api VUE_APP_BASE_API='https://cz-hjjc.115.langye.net' -VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/admin/upload-file' +VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/upload-file' VUE_APP_PREVIEW=//view.langye.net/preview/onlinePreview VUE_APP_MODULE_NAME=oa diff --git a/.env.production b/.env.production index 5f0ae3f..6f8604e 100644 --- a/.env.production +++ b/.env.production @@ -3,6 +3,6 @@ ENV = 'production' # base api VUE_APP_BASE_API='https://cz-hjjc.115.langye.net' -VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/admin/upload-file' +VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/upload-file' VUE_APP_PREVIEW=//view.langye.net/preview/onlinePreview VUE_APP_MODULE_NAME=oa diff --git a/.env.staging b/.env.staging index 62783ab..54b7547 100644 --- a/.env.staging +++ b/.env.staging @@ -5,6 +5,6 @@ ENV = 'staging' # base api VUE_APP_BASE_API='https://cz-hjjc.115.langye.net' -VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/admin/upload-file' +VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/upload-file' VUE_APP_PREVIEW=//view.langye.net/preview/onlinePreview VUE_APP_MODULE_NAME=oa diff --git a/src/api/flow/index.js b/src/api/flow/index.js index 13959a6..30482ff 100644 --- a/src/api/flow/index.js +++ b/src/api/flow/index.js @@ -8,19 +8,18 @@ export function flow(isLoading=false) { }) } -export function flowList(params, type) { +export function preConfig(custom_model_id,isLoading=false) { return request({ method: 'get', - url: `/api/oa/flow/list/${type}`, - params + url: `/api/oa/flow/create-pre/${custom_model_id}`, + isLoading }) } - -export function preConfig(custom_model_id,isLoading=false) { +export function fieldConfig(custom_model_id,isLoading=false) { return request({ method: 'get', - url: `/api/oa/flow/create-pre/${custom_model_id}`, + url: `/api/oa/flow/custom-model-fields/${custom_model_id}`, isLoading }) } @@ -29,10 +28,20 @@ export function create(data,custom_model_id) { return request({ method: 'post', url: `/api/oa/flow/create/${custom_model_id}`, - data: qs.stringify(data, { arrayFormat: 'brackets' }), - headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - }, + data + // data: qs.stringify(data, { arrayFormat: 'brackets' }), + // headers: { + // 'Content-Type': 'application/x-www-form-urlencoded' + // }, + }) +} + +export function preDeal(flow_id,params,isLoading=false) { + return request({ + method: 'get', + url: `/api/oa/flow/deal-pre/${flow_id}`, + params, + isLoading }) } @@ -43,3 +52,30 @@ export function deal(data,flow_id) { data }) } + +export function checkIsThroughNode(params,isLoading=false) { + return request({ + method: 'get', + url: '/api/oa/flow/check-is-through-node', + params, + isLoading + }) +} + +export function getNextNodeUsers(params,isLoading=false) { + return request({ + method: 'get', + url: '/api/oa/flow/get-next-node-users', + params, + isLoading + }) +} + +//查看列表相关 +export function flowList(type,params,isLoading = false) { + return request({ + method: 'get', + url: `/api/oa/flow/list/${type}`, + isLoading + }) +} diff --git a/src/main.js b/src/main.js index 72bc58c..6782a32 100644 --- a/src/main.js +++ b/src/main.js @@ -32,16 +32,18 @@ if (process.env.NODE_ENV === 'production') { //Vue.use(ElementUI, { locale }) // 如果想要中文版 element-ui,按如下方式声明 Vue.use(ElementUI) -import { VxeIcon, VxeTable, VxeColumn, VxeColgroup, VxeTableEditModule, VxeTableValidatorModule, VxeModal, VxeToolbar } from "vxe-table"; +import { VxeButton, VxeIcon, VxeTable, VxeColumn, VxeColgroup, VxeModal, VxeToolbar, VxeTableEditModule, VxeTableValidatorModule, VxeTableExportModule } from "vxe-table"; import "vxe-table/styles/index.scss" Vue.use(VxeTableEditModule); Vue.use(VxeTableValidatorModule); +Vue.use(VxeTableExportModule); Vue.use(VxeIcon); Vue.use(VxeTable); Vue.use(VxeColumn); Vue.use(VxeColgroup); Vue.use(VxeModal); Vue.use(VxeToolbar); +Vue.use(VxeButton); Vue.config.productionTip = false diff --git a/src/router/index.js b/src/router/index.js index 7a0e6e0..60c2a92 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -65,6 +65,11 @@ export const constantRoutes = [ name: 'flowIndex', component: () => import('@/views/flow/index.vue'), meta: { title: '流程创建', icon: 'tree' } + },{ + path: '/list', + name: 'flowList', + component: () => import('@/views/flow/list.vue'), + meta: { title: '流程监管', icon: 'table', type: 'created-by-me' } },{ path: 'create', name: 'create', diff --git a/src/utils/formBuilder.js b/src/utils/formBuilder.js index aa7818e..0a046b4 100644 --- a/src/utils/formBuilder.js +++ b/src/utils/formBuilder.js @@ -13,6 +13,13 @@ import { deepCopy } from "@/utils/index"; **/ export default function formBuilder (device, info, h, row, pWrite=false) { let formItem; + //下拉选项 + if(info?.stub) { + options = info?.stub?.split('|') || [] + } else if (info?.selection_model) { + options = info.selection_model_items + } + let options; if (device === 'desktop') { if(info._writeable || (info.type === 'relation' && info._readable) || pWrite) { switch (info.type) { @@ -201,6 +208,9 @@ export default function formBuilder (device, info, h, row, pWrite=false) { clearable: true, placeholder: info.help_text }, + style: { + width: '100%' + }, attrs: { placeholder: info.help_text }, @@ -209,11 +219,11 @@ export default function formBuilder (device, info, h, row, pWrite=false) { row ? this.$set(row,info.name,e) : this.$set(this.form,info.name,e) } } - },[1,2,3].map(option => ( + },options.map(option => ( h('el-option',{ props: { - label: option, - value: option + label: typeof option === 'object' ? option.name : option, + value: typeof option === 'object' ? option.id : option, } }) ))) @@ -231,12 +241,12 @@ export default function formBuilder (device, info, h, row, pWrite=false) { row ? this.$set(row,info.name,e) : this.$set(this.form,info.name,e) } } - },[1,2,3].map(option => ( + },options.map(option => ( h('el-radio',{ props: { - label: option + label: typeof option === 'object' ? option.id : option } - },option) + },typeof option === 'object' ? option.name : option) ))) break; case 'file': @@ -259,6 +269,11 @@ export default function formBuilder (device, info, h, row, pWrite=false) { } }, onSuccess: (response, file, fileList) => { + fileList.forEach(file => { + if(file.response?.data && !file.response?.code) { + file.response = file.response.data + } + }) this.file[info.name] = fileList; }, onRemove: (file, fileList) => { @@ -383,7 +398,7 @@ export default function formBuilder (device, info, h, row, pWrite=false) { row ? this.$set(row,info.name,e) : this.$set(this.form,info.name,e) } } - },[1,2,3].map(option => ( + },options.map(option => ( h('el-option',{ props: { label: option, @@ -408,7 +423,7 @@ export default function formBuilder (device, info, h, row, pWrite=false) { row ? this.$set(row,info.name,e) : this.$set(this.form,info.name,e) } } - },[1,2,3].map(option => ( + },options.map(option => ( h('el-option',{ props: { label: option, @@ -540,108 +555,126 @@ export default function formBuilder (device, info, h, row, pWrite=false) { } } if(device === 'mobile') { - switch (info.type) { - case 'text': - formItem = h(formBuilderMap(device).get(info.type),{ - props: { - name: info.name, - label: info.label, - value: this.form[info.name], - clearable: true, - placeholder: info.help_text - }, - attrs: { - placeholder: info.help_text - }, - on: { - input: e => { - this.$set(this.form,info.name,e) + if(info._writeable || pWrite) { + switch (info.type) { + case 'text': + formItem = h(formBuilderMap(device).get(info.type),{ + props: { + name: info.name, + label: info.label, + value: row ? row[info.name] : this.form[info.name], + clearable: true, + placeholder: info.help_text + }, + attrs: { + placeholder: info.help_text + }, + on: { + input: e => { + this.$set(this.form,info.name,e) + } } - } - }) - break; - case 'textarea': - formItem = h(formBuilderMap(device).get(info.type),{ - props: { - name: info.name, - label: info.label, - type: 'textarea', - value: this.form[info.name], - clearable: true, - placeholder: info.help_text - }, - attrs: { - placeholder: info.help_text - }, - on: { - input: e => { - this.$set(this.form,info.name,e) + }) + break; + case 'textarea': + formItem = h(formBuilderMap(device).get(info.type),{ + props: { + name: info.name, + label: info.label, + type: 'textarea', + value: row ? row[info.name] : this.form[info.name], + clearable: true, + placeholder: info.help_text + }, + attrs: { + placeholder: info.help_text + }, + on: { + input: e => { + this.$set(this.form,info.name,e) + } } - } - }) - break; - case 'date': - formItem = h('van-field',{ - props: { - readonly: true, - clickable: true, - name: info.name, - label: info.label, - value: this.form[info.name], - clearable: true, - placeholder: info.help_text, - }, - attrs: { - placeholder: info.help_text - }, - on: { - click: _ => { - this.vanCalendarOption.forFormName = info.name; - this.$set(this.vanCalendarOption,'isShow',true); + }) + break; + case 'date': + formItem = h('van-field',{ + props: { + readonly: true, + clickable: true, + name: info.name, + label: info.label, + value: row ? row[info.name] : this.form[info.name], + clearable: true, + placeholder: info.help_text, + }, + attrs: { + placeholder: info.help_text + }, + on: { + click: _ => { + this.vanCalendarOption.forFormName = info.name; + this.$set(this.vanCalendarOption,'isShow',true); + } } - } - }) - break; - case 'datetime': - formItem = h('van-field',{ - props: { - readonly: true, - clickable: true, - name: info.name, - label: info.label, - value: this.form[info.name], - clearable: true, - placeholder: info.help_text, - }, - on: { - click:_ => { - this.vanTimePickerOption.forFormName = info.name; - this.$set(this.vanTimePickerOption,'isShow',true); + }) + break; + case 'datetime': + formItem = h('van-field',{ + props: { + readonly: true, + clickable: true, + name: info.name, + label: info.label, + value: row ? row[info.name] : this.form[info.name], + clearable: true, + placeholder: info.help_text, + }, + on: { + click:_ => { + this.vanTimePickerOption.forFormName = info.name; + this.$set(this.vanTimePickerOption,'isShow',true); + } } - } - }) - break; - case 'select': - formItem = h('van-field',{ - props: { - readonly: true, - clickable: true, - name: info.name, - label: info.label, - value: this.form[info.name], - clearable: true, - placeholder: info.help_text, - }, - on: { - click:_ => { - this.vanPopupOption.forFormName = info.name; - this.$set(this.vanPopupOption,'columns',['杭州', '宁波', '温州', '嘉兴', '湖州']); - this.$set(this.vanPopupOption,'isShow',true); + }) + break; + case 'select': + formItem = h('van-field',{ + props: { + readonly: true, + clickable: true, + name: info.name, + label: info.label, + value: row ? row[info.name] : this.form[info.name], + clearable: true, + placeholder: info.help_text, + }, + on: { + click:_ => { + this.vanPopupOption.forFormName = info.name; + this.$set(this.vanPopupOption,'columns',options); + this.$set(this.vanPopupOption,'isShow',true); + } } - } - }) - break; + }) + break; + case 'relation': + formItem = h('div',this.form[info.name].map((sForm,sIndex) => ( + h('van-cell',{ + props: { + 'arrow-direction': 'down', + title: info.label + } + },[ + h('van-form',{ + props: { + 'scroll-to-error': true + } + },Array.from(this.subForm).map(i => i[1]?.customModel?.fields)?.flat().map(subField => formBuilder.bind(this)(device, subField, h, sForm, info._writeable))) + ]) + ))) + break; + } + return formItem } - return formItem } } diff --git a/src/utils/validate.js b/src/utils/validate.js index 8d962ad..f059be6 100644 --- a/src/utils/validate.js +++ b/src/utils/validate.js @@ -18,3 +18,12 @@ export function validUsername(str) { const valid_map = ['admin', 'editor'] return valid_map.indexOf(str.trim()) >= 0 } + +export const validation = new Map([ + ['integer',/^-?\d+$/],//整数 + ['date',/(^\d{10})|(^\d{13})|(^((\d\d\d\d(.+)|\d\d(.+))?(0?[1-9](.+)|1[012](.+))?((0?[1-9]|[12]\d|3[01])(.+))?\s?)((0?[0-9]|1[0-9]|2[0-3])(.+))?((0?[0-9]|[1-5][0-9])(.+))?((0?[0-9]|[1-5][0-9])(.+))?)$/], + ['email',/^[^\s@]+@[^\s@]+\.[^\s@]+$/], + ['idcard',/(^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3})|(^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])$/], + ['mobile',/(^1[3456789]\d{9})|(^(0\d{2,3}(-)*)?\d{7})$/], + ['numeric',/^-?\d+(.\d+)?$/], +]) diff --git a/src/views/flow/DesktopForm.vue b/src/views/flow/DesktopForm.vue index 7d2e3ff..08b992f 100644 --- a/src/views/flow/DesktopForm.vue +++ b/src/views/flow/DesktopForm.vue @@ -36,7 +36,8 @@ export default { type: Object, default: () => ({}), required: true - } + }, + scriptContent: String }, data() { return { @@ -61,6 +62,15 @@ export default { }, fileList(newVal) { this.file = deepCopy(newVal) + }, + scriptContent(newVal) { + if(newVal) { + try { + new Function(newVal).bind(this)() + } catch (err) { + console.error(err) + } + } } }, render(h) { diff --git a/src/views/flow/MobileForm.vue b/src/views/flow/MobileForm.vue index 1dc7c95..e9dbbf8 100644 --- a/src/views/flow/MobileForm.vue +++ b/src/views/flow/MobileForm.vue @@ -1,18 +1,45 @@ + + diff --git a/vue.config.js b/vue.config.js index 77a1f3c..99c8235 100644 --- a/vue.config.js +++ b/vue.config.js @@ -24,8 +24,8 @@ module.exports = { * In most cases please use '/' !!! * Detail: https://cli.vuejs.org/config/#publicpath */ - publicPath: '/oa', - outputDir: 'dist', + publicPath: '/oaw', + outputDir: '../cz_hjjc/public/oaw', assetsDir: 'static', lintOnSave: process.env.NODE_ENV === 'development', productionSourceMap: false,