| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416 |
- <template>
- <view class="process_container">
- <uni-card spacing="0">
- <view class="main_container">
- <uni-forms label-position="left" :label-width="125" :border="true">
- <view v-for="(elem, index) in formElements">
- <uni-forms-item v-if="!('0' == elem.canEdit && elem.elementName.slice(-2) == '审批' && elem.elementName.slice(-2) == '意见' && elem.elementName.slice(-2) == '批示')" :label="elem.elementName" :key="index">
- <uni-easyinput v-if="'多少小时' == elem.elementName" :disabled="true" placeholder=""
- v-model="diffHours"></uni-easyinput>
- <!-- 输入框 -->
- <uni-easyinput v-else-if="'0' == elem.type" :disabled="'0' == elem.canEdit"
- :placeholder="'0' == elem.canEdit ? '' : '请输入内容'"
- v-model="elem.defaultValue"></uni-easyinput>
- <!-- 富文本输入框 -->
- <uni-easyinput v-else-if="'1' == elem.type" :disabled="'0' == elem.canEdit"
- :placeholder="'0' == elem.canEdit ? '' : '请输入内容'" v-model="elem.defaultValue"
- type="textarea"></uni-easyinput>
- <!-- 下拉框 -->
- <picker class="picker_container" v-else-if="'2' == elem.type"
- @change="bindPickerChange($event, elem)" :value="elem.defaultValue"
- :range="formatDict(elem.typeDetail.enum)">
- <view class="uni-input input_text">
- <!-- 设置默认值为第一个选项 -->
- {{ elem.defaultValue ? elem.defaultValue : elem.defaultValue =
- elem.typeDetail.enum[0].enumVname }}
- </view>
- </picker>
- <!-- 开始时间选择器 -->
- <uni-datetime-picker :end="endTime" @change="setTimeRange(elem)"
- v-else-if="timeFlag && '9' == elem.type && '开始时间' == elem.elementName"
- v-model="elem.defaultValue" :clear-icon="false" type="datetime" />
- <!-- 结束时间选择器 -->
- <uni-datetime-picker :start="startTime" @change="setTimeRange(elem)" :disabled="disableEndTime"
- :placeholder="disableEndTime ? '请先确认开始时间' : '确认结束时间'"
- v-else-if="timeFlag && '9' == elem.type && '结束时间' == elem.elementName"
- v-model="elem.defaultValue" :clear-icon="false" type="datetime" />
- <!-- 其他时间选择器 -->
- <!-- 年月日 时分秒 -->
- <uni-datetime-picker v-else-if="'9' == elem.type" v-model="elem.defaultValue" type="datetime" />
- <!-- 年月日 -->
- <uni-datetime-picker v-else-if="'3' == elem.type" v-model="elem.defaultValue" type="date" />
- </uni-forms-item>
- </view>
- </uni-forms>
- </view>
- </uni-card>
- <view v-if="repeatingForm.elementItem.length > 0" class="repeating_table">
- <uni-card v-for="(table, tableIndex) in repeatingForm.elements" spacing="0" :key="tableIndex">
- <uni-forms label-position="left" :label-width="125" :border="true">
- <uni-forms-item v-for="(elem, itemIndex) in table"
- :label="repeatingForm.elementItem[itemIndex].elementName.slice(3)" :key="itemIndex">
- <uni-easyinput v-if="repeatingForm.elementItem[itemIndex].bddzText" :disabled="true"
- :placeholder="''" :value="computedrepeatingFormItemValue(elem, table)"></uni-easyinput>
- <uni-easyinput v-else placeholder="请输入内容" v-model="elem.value"></uni-easyinput>
- </uni-forms-item>
- </uni-forms>
- <view class="repeating_table_button_container">
- <uni-row>
- <uni-col :span="10" :offset="1">
- <button @click="addrepeatingFormItem(tableIndex)" type="primary">新增</button>
- </uni-col>
- <uni-col :span="10" :offset="2">
- <button @click="delrepeatingFormItem(tableIndex)"
- :disabled="repeatingForm.elements.length <= 1" type="warn">删除</button>
- </uni-col>
- </uni-row>
- </view>
- </uni-card>
- </view>
- <uni-card title="上传附件" :extra="`${fileList.length}/15`" spacing="0">
- <uni-file-picker ref="filePicker" v-model="fileList" :auto-upload="true" mode="list" limit="10"
- file-mediatype="all" @select="handleFileSelect" @progress="handleFileProgress"
- @success="handleFileSuccess" @fail="handleFileFail" @delete="handleFileDelete" />
- </uni-card>
- <view class="submit_button_container">
- <uni-card spacing="0" padding="0">
- <button :loading="!button_state" type="primary" class="submit_button" @click="submitProcess">提交</button>
- </uni-card>
- </view>
- </view>
- <view style="height: 5px; margin-top: 10px;"></view>
- </template>
- <script setup lang="ts">
- import { onMounted, reactive, ref, computed } from 'vue'
- import { onLoad } from '@dcloudio/uni-app'
- import { useUserStore } from '@/store/user.js'
- import $modal from '@/plugins/modal.js'
- import $tab from '@/plugins/tab.js'
- import { convertToChineseCurrency } from '@/utils/ygoa.js'
- import { getProcessInfo, getProcessForm, submitProcessForm, uploadFile } from '@/api/work.js'
- let processInfo = reactive({
- modelName: '流程申请',
- control: '',
- formId: '',
- modelId: '',
- tmodelId: '',
- isMoreIns: '',
- pathJudgeType: '',
- form: []
- })
- const userStore = useUserStore()
- const title = ref('')
- onLoad((options) => {
- const { modelName, modelId, control } = options
- processInfo.modelName = modelName
- processInfo.modelId = modelId
- processInfo.control = control
- title.value = userStore.user.name + '的' + processInfo.modelName
- // 设置导航栏标题
- uni.setNavigationBarTitle({
- title: title.value
- });
- })
- onMounted(() => {
- initProcessInfo().then(() => {
- initProcessForm()
- })
- })
- function initProcessInfo() {
- return new Promise<void>((resolve, reject) => {
- getProcessInfo(processInfo)
- .then(({ returnParams }) => {
- const { formId, tmodelId, isMoreIns, pathJudgeType } = returnParams.flow[0]
- processInfo.formId = formId
- processInfo.tmodelId = tmodelId
- processInfo.isMoreIns = isMoreIns
- processInfo.pathJudgeType = pathJudgeType
- resolve()
- })
- })
- }
- function initProcessForm() {
- getProcessForm(userStore.user, processInfo).then(({ returnParams }) => {
- formElements.value = returnParams.formElements
- repeatingForm.value = returnParams.repeatingForm
- // 生成第一个重复表数据
- if (repeatingForm.value) {
- addrepeatingFormItem(0)
- }
- startEleIndex.value = formElements.value.findIndex((item) => '开始时间' == item.elementName)
- endEleIndex.value = formElements.value.findIndex((item) => '结束时间' == item.elementName)
- // console.log('startEle', startEleIndex.value);
- // console.log('endEle', endEleIndex.value);
- if (startEleIndex.value != -1 && endEleIndex.value != -1) { // 判断是否需要计算时间差
- // console.log('if (startEleIndex && endEleIndex)');
- timeFlag.value = true
- disableEndTime.value = true // 计算时间差时默认禁用结束时间选择器
- formElements.value[startEleIndex.value].defaultValue = new Date()
- }
- })
- }
- const formElements = ref([])
- const repeatingForm = ref({
- elementItem: [],
- elements: []
- })
- const startEleIndex = ref(0) // 开始时间
- const endEleIndex = ref(0) // 结束时间
- function addrepeatingFormItem(index) {
- const table = repeatingForm.value.elementItem.map(({ tableField, bddzText }) => {
- const item = {
- name: tableField,
- value: ""
- }
- if (bddzText != '') {
- const mulItem = bddzText.split('*')
- item['bddzText'] = mulItem.map(item => {
- return repeatingForm.value.elementItem.findIndex(({ elementName }) => item == elementName)
- })
- }
- return item
- })
- repeatingForm.value.elements.splice(index + 1, 0, table)
- }
- function delrepeatingFormItem(index) {
- console.log("delrepeatingFormItem: " + index);
- $modal.confirm('', '确认删除该重复表数据')
- .then(() => {
- repeatingForm.value.elements.splice(index, 1)
- }).catch(() => { })
- }
- function computedrepeatingFormItemValue(item, table) {
- let res = 1
- item.bddzText.forEach(itemIndex => {
- res = res * table[itemIndex].value
- })
- item.value = res
- console.log('convertToChineseCurrency', convertToChineseCurrency(res));
- return res
- }
- // 下拉框
- function bindPickerChange(e, item) {
- const index = e.detail.value;
- item.defaultValue = item.typeDetail.enum[index].enumVname
- }
- function formatDict(dict) {
- return dict.map(({ enumVname }) => enumVname)
- }
- const startTime = ref(0) // 开始时间
- const endTime = ref(0) // 结束时间
- const diffHours = ref(' ') // 时间差
- const timeFlag = ref(false) // 是否计算时间差
- const disableEndTime = ref(false) // 禁用 结束时间选择器
- function setTimeRange(e) {
- if (timeFlag.value && '开始时间' == e.elementName) {
- startTime.value = e.defaultValue // 设置 开始时间
- disableEndTime.value = false // 解除 结束时间选择器 禁用
- }
- if (timeFlag.value && '结束时间' == e.elementName) {
- endTime.value = e.defaultValue // 设置 结束时间
- }
- if (timeFlag.value && startTime.value && endTime.value) {
- const start = new Date(startTime.value).getTime() // 获取 开始时间 时间戳
- const end = new Date(endTime.value).getTime() // 获取 结束时间 时间戳
- const diffSec = Math.abs(end - start) // 获取 时间戳 差值
- diffHours.value = (diffSec / 1000 / 60 / 60).toFixed(2) // 计算 时间差值 并格式化 为只有2位小数
- }
- }
- const fileList = ref([]) // 文件列表
- const fileSeqs = ref([]) // 文件上传返回 seq 列表
- const filePicker = ref(null)
- // TODO 中间数组缓存将要上传的文件列表 保存上传顺序 上传成功后保存seq后再添加入 实际文件列表渲染
- async function handleFileSelect(files) { // 新增文件
- console.log('handleFileSelect', files.tempFiles)
- files.tempFiles.forEach(file => {
- const data = {
- name: file.name,
- filePath: file.path,
- }
- uploadFile(data) // TODO 改为同步
- .then(res => {
- fileSeqs.value.push(res.returnParams)
- file.seq = res.returnParams
- fileList.value.push(file)
- // file.seq = res.returnParams
- })
- .catch(err => {
- $modal.msgError('文件' + data.name + '上传失败,请重新上传')
- switch (err) {
- case -201:
- console.log('文件上传失败 未找到该文件');
- break;
- case -20201:
- console.log('文件上传失败 返回值不是JSON字符串');
- break;
- }
- // files.tempFiles.filter(item => item.path == file.path)
- })
- })
- console.log('UploadFiles', files.tempFiles);
- }
- function handleFileProgress(file, progress) {
- // console.log('handleFileProgress', file, progress);
- }
- function handleFileSuccess(file, res) {
- // console.log('handleFileSuccess', file, res);
- }
- function handleFileFail(file, err) {
- // console.log('handleFileFail', file, err);
- }
- function handleFileDelete(file, index) { // 移除文件
- console.log('handleDelete', file, index)
- console.log('index', file)
- fileList.value.splice(fileList.value.indexOf(file.tempFiles), 1)
- fileSeqs.value.splice(index, 1)
- }
- const button_state = ref(true)
- function submitProcess() { // 提交表单
- // 禁用提交按钮
- button_state.value = false
- // 保存表单数据
- processInfo.form = formElements.value.map(({ tableField, defaultValue }) => {
- return { name: tableField, value: defaultValue }
- })
- repeatingForm.value.elements.forEach((item, index) => {
- const newItem = item.map(({ name, value }) => {
- return {
- name: name + '_' + (index + 1),
- value
- }
- })
- processInfo.form.push(...newItem)
- })
- button_state.value = true
- // return
- submitProcessForm(userStore.user, processInfo, fileSeqs.value).then(res => {
- console.log('submitProcessForm', res);
- if (res.returnMsg.includes('提交失败')) {
- // 启用提交按钮
- button_state.value = true
- $modal.msgError(res.returnMsg)
- } else {
- $modal.msgSuccess(res.returnMsg)
- // 通知列表刷新数据
- uni.$emit('ReloadProcessData');
- setTimeout(() => {
- // 返回上一页
- $tab.navigateBack();
- }, 1000)
- }
- })
- }
- </script>
- <style lang="scss">
- .process_container {
- position: relative;
- .main_container {
- min-height: 50vh;
- }
- .picker_container {
- border: 1px solid #e5e5e5;
- background-color: #fff;
- border-radius: 4px;
- // box-sizing: border-box;
- .input_text {
- color: #333;
- font-size: 14px;
- line-height: 35px;
- height: 35px;
- padding: 0 0 0 10px;
- }
- }
- .repeating_table {
- .uni-forms-item--border {
- padding: 5px 0 !important;
- }
- .repeating_table_button_container {
- margin-top: 5px;
- button {
- height: 36px;
- line-height: 36px;
- color: #fff;
- }
- .add {
- background-color: #1ca035;
- }
- .del {
- background-color: #e64340;
- }
- }
- }
- .is-disabled {
- color: #666 !important;
- }
- .submit_button_container{
- position: sticky;
- z-index: 10;
- width: 100%;
- bottom: 10px;
- .submit_button {
- background-color: #007aff !important;
- color: #fff !important;
- }
- .submit_button::after {
- border: 1px solid rgba(0, 0, 0, .2);
- border-radius: 10px;
- box-sizing: border-box;
- content: " ";
- height: 200%;
- left: 0;
- position: absolute;
- top: 0;
- -webkit-transform: scale(.5);
- transform: scale(.5);
- -webkit-transform-origin: 0 0;
- transform-origin: 0 0;
- width: 200%;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-style: solid;
- border-right-style: solid;
- border-bottom-style: solid;
- border-left-style: solid;
- border-top-color: rgba(0, 0, 0, 0.2);
- border-right-color: rgba(0, 0, 0, 0.2);
- border-bottom-color: rgba(0, 0, 0, 0.2);
- border-left-color: rgba(0, 0, 0, 0.2);
- border-image-source: initial;
- border-image-slice: initial;
- border-image-width: initial;
- border-image-outset: initial;
- border-image-repeat: initial;
- border-top-left-radius: 10px;
- border-top-right-radius: 10px;
- border-bottom-right-radius: 10px;
- border-bottom-left-radius: 10px;
- }
- }
- }
- </style>
|